All vulnerabilities
GHSA-vx2p-7hhm-wv62

surrealdb: Cross-tenant access through the Surreal-NS / Surreal-DB headers with Basic authentication

surrealdb
CVSS
9.6Critical
ExploitationNo known exploitationNot in CISA KEV, which does not prove it is unexploitedCISA KEV
Exploit odds (EPSS)No scoreNo FIRST EPSS score in this snapshot yet
Fixed in3.3.0Fixed versionGitHub
Published28 Sep 2026Updated 28 Sep 2026GitHub

What fixes it

A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.

Description

A database user of one tenant could read and write another tenant's data over HTTP by authenticating to their own tenant and selecting the other in the same request.

With HTTP Basic authentication, the account was verified against the namespace/database named in the Surreal-Auth-NS / Surreal-Auth-DB headers. The session's *selected* namespace/database came from the separate Surreal-NS / Surreal-DB headers and was never checked against the level the caller authenticated at. After the switch, the caller's identity stayed bound to their own tenant, but queries ran against the foreign one, where the only remaining gate was the table's PERMISSIONS clause. So a table declared PERMISSIONS FULL, or with a predicate the caller happened to satisfy, admitted the request. That is a common table shape when the namespace/database itself is treated as the tenant boundary.

For example, a database VIEWER of attacker_ns/attacker_db sending Surreal-Auth-NS: attacker_ns and Surreal-Auth-DB: attacker_db, but Surreal-NS: victim_ns and Surreal-DB: victim_db, could SELECT * FROM secrets on POST /sql and read the victim tenant's rows. They could also create rows there and call its PERMISSIONS FULL functions.

The same root cause was reported through several paths, each published as its own advisory and all fixed in 3.3.0:

Impact

What an attacker can do:

  • With a database-level account in any one tenant (a VIEWER is enough), select another tenant through the Surreal-NS / Surreal-DB headers. They can then read, create, and modify rows in its tables, and call its functions, wherever PERMISSIONS allow it, such as PERMISSIONS FULL. The account's own role does not limit this, because an out-of-scope caller is judged only by the table's PERMISSIONS.

What it can't do:

  • Reach any tenant without valid credentials for some namespace/database on the instance. This is not an unauthenticated bypass.
  • Read or write a table whose relevant PERMISSIONS clause denies the operation, including PERMISSIONS NONE (the DEFINE TABLE default).
  • Pass IAM-gated operations such as INFO FOR DB, or change roles.
  • Affect single-tenant deployments, or callers that already hold instance-wide (root) scope.

Patches

A request can no longer select a namespace/database outside the caller's authenticated level. The check applies to the USE statement, the RPC use method, and HTTP sessions built from the Surreal-NS / Surreal-DB headers. Root can select any namespace/database, and a namespace user any database in their namespace. Database and record users can select only their own namespace/database. Anonymous callers remain governed by table PERMISSIONS.

The query-time scope checks now apply to every scoped principal, not only record users. They also cover record fetches and the document write pipeline, so a read or write in a foreign tenant is refused however the session reached it.

  • Versions 3.3.0 and later are not affected by this issue.

Workarounds

Users unable to patch should consider the following workarounds:

  • On shared instances, use separate deployments, not namespace/database boundaries, to isolate tenants. Until you upgrade, issue namespace-, database-, and record-level credentials only to parties trusted with every tenant on the instance.
  • Prefer a PERMISSIONS WHERE clause that checks the caller's identity, such as $auth or a token claim, over PERMISSIONS FULL. This reduces exposure but does not restore the boundary.

References

Acknowledgements

Thank you to Alpastx for reporting this issue.

Text from GitHub Advisory Database

Affected versions 1

  • surrealdb, rust< 3.3.0GitHub