Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-46552 — NocoDB Shared-Base Links Could Invite Real Base Members and Survive Share Revocation | Kitploit
Tools/GitHubGitHub/0xmrma/cve-2026-46552
Authentication & AuthorizationVulnerability AnalysisWeb Application ExploitationPenetration TestingPapers & ResearchLearning & Education
GitHub0xmrma/cve-2026-46552

CVE-2026-46552

NocoDB Shared-Base Links Could Invite Real Base Members and Survive Share Revocation

View Repository
373 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-46552

NocoDB Shared-Base Links Could Invite Real Base Members and Survive Share Revocation

Intro

I found this issue while reviewing NocoDB, with a simple security question in mind:

Can a public shared-base link cross the boundary from temporary shared access into real authenticated base membership?

In this case, the answer was yes.

A shared-base session authenticated only by xc-shared-base-id was treated as a normal base viewer for ACL purposes. Because viewer permissions still reached member-management endpoints, a user with only the shared-base UUID could enumerate existing base members and invite an arbitrary email address into the base as a real member.

That invited user could then redeem the invite through the normal signup flow, obtain a standard authenticated account, and keep base access even after the owner disabled the shared-base link.

That issue became CVE-2026-46552.

Project: NocoDB

Affected version validated: 0.301.3

This affected NocoDB, on its official site, NocoDB is presented as trusted by 35,000+ organizations, with 20+ million downloads. The site also lists companies such as Accenture, Western Digital, Hyundai, Walmart, PwC, Bosch, and American Express.

photo0

Attack Chain

public shared-base link -> xc-shared-base-id treated as normal base viewer -> viewer ACL reaches member-management endpoints -> attacker lists base users and invites arbitrary email -> invited user redeems normal signup token -> durable authenticated base access survives shared-link revocation


What NocoDB Does

NocoDB is a database-oriented collaboration platform that exposes browser-based base access, sharing, metadata management, and user membership workflows.

That means its sharing model is a real security boundary.

The important question here was not whether shared-base links can read shared content.

The real question was:

Can a public share principal perform actions that should belong only to authenticated base members?

In this case, it could.


Why This Surface Was Worth Looking At

Public sharing features are easy to underestimate.

That is a mistake.

Once an application supports:

  • anonymous or link-based access,
  • role mapping,
  • and ordinary authenticated management APIs behind the same ACL system,

the main risk is not just data exposure.

The stronger risk is boundary collapse:

  • a lower-trust principal inherits higher-trust capabilities,
  • management actions become reachable from a public-share context,
  • and temporary access can be converted into persistent access.

That was the real issue here.

This was not a bug in login validation. It was not a token forgery issue. It was not a password-reset flaw.

It was a classic authorization boundary failure:

  • a shared-link principal was mapped into normal base roles,
  • those roles still included member-management capabilities,
  • and real durable access-control state could then be modified from the public-share context.

The Boundary I Focused On

I did not approach this by randomly probing endpoints and hoping something interesting would respond.

The stronger path was to identify the highest-value trust boundary first.

For NocoDB, that was the boundary between:

  • shared-base access
  • and authenticated base membership

Those two states should not be interchangeable.

A shared-base link is supposed to represent scoped, revocable, link-based access. It should not be able to mint new long-lived principals inside the base.

That is the exact boundary that failed here.


Root Cause

The vulnerability came from how shared-base access was integrated into the normal ACL path.

In the shared-base frontend flow, xc-shared-base-id was injected while ordinary auth headers were removed.

Then, in the backend, BaseViewStrategy accepted xc-shared-base-id and translated the shared link directly into ordinary roles / base_roles derived from the shared-base configuration.

That was the first problem.

The second problem was that viewer-level permissions still included member-management actions.

In the ACL layer, ProjectRoles.VIEWER could reach:

  • baseUserList
  • userInvite

Those permissions guarded normal meta routes:

  • GET /api/v2/meta/bases/:baseId/users
  • POST /api/v2/meta/bases/:baseId/users

So a public-share session was effectively allowed to hit membership endpoints intended for real base participants.

The last step was in the invite flow itself.

BaseUsersService.userInvite() checked role power, then created:

  • a real user row with an invite_token
  • a real base-membership row for the target base

And for shared-base sessions:

  • invited_by became null

because there was no real authenticated inviter identity behind the request.

That is the whole bug chain.

Why this is exploitable

Because possession of a shared-base link was enough.

The attacker did not need:

  • xc-auth
  • a pre-existing account
  • stolen credentials
  • or prior membership in the base

The exploit chain was straightforward:

  • attacker obtains a shared-base UUID
  • the UUID is accepted as a base viewer principal
  • viewer ACL reaches member-management endpoints
  • attacker lists current base members
  • attacker invites an arbitrary email address
  • the invited user redeems the token through the normal signup flow
  • the new account becomes a real authenticated base member
  • the owner later disables the shared link
  • the invited account still keeps normal authenticated access

That converts revocable link-sharing into durable membership.


What Makes This a Security Issue, Not Just Odd Sharing Behavior

The important distinction is persistence across revocation.

This was not just:

"a viewer could call a viewer endpoint"

The vulnerable principal was not a normal authenticated viewer.

It was a public-share session.

That matters because the application treated a transient, link-scoped principal as if it were trusted enough to:

  • enumerate real members,
  • change access-control state,
  • and create new durable principals inside the base

The real question was not:

"Can a shared user read shared data?"

The real question was:

"Can public-share access be converted into permanent authenticated access that survives share revocation?"

The answer was yes.

That is why this is a real authorization vulnerability rather than just surprising application behavior.


PoC

I validated this locally against:

  • product version: 0.301.3
  • commit: dac49b0122c5ee655fb8f46a1b6e42dfeec1f3ad
  • base URL: http://127.0.0.1:8080

The reproduction was straightforward.

First, I signed in as a normal owner account, created a fresh base, created a table, and enabled shared-base access as viewer:

PATCH /api/v2/meta/bases/<baseId>/shared
Content-Type: application/json

{
  "roles": "viewer"
}

That returned the shared-base UUID.

Then, without sending any xc-auth, I used only:

xc-shared-base-id: <sharedBaseUuid>

Using only that header, I called:

GET /api/v2/meta/bases/<baseId>/users

That returned 200 OK and exposed real base members, including email addresses.

Still using only xc-shared-base-id, I called:

POST /api/v2/meta/bases/<baseId>/users
Content-Type: application/json

{
  "email": "[email protected]",
  "roles": "viewer"
}

That also returned 200 OK.

For local lab validation without email delivery, I confirmed directly in the SQLite meta database that:

  • nc_users_v2 contained the invited user with a non-null invite_token
  • nc_base_users_v2 contained a real membership row for the target base
  • invited_by was NULL
Download Tool