{"schema":"threatline.record/2","record":{"id":"GHSA-w5v9-jc5f-5rmc","aliases":["GHSA-w5v9-jc5f-5rmc"],"summary":"Cross-tenant access for system users through the Surreal-NS / Surreal-DB headers and the RPC use method","details":"A system user (created with `DEFINE USER … ON DATABASE` or `ON NAMESPACE`) scoped to one tenant could read, create, modify, and delete rows in another tenant, and read the value of a `DEFINE PARAM` there.\n\nThe selected namespace/database came from caller-controlled input and was never compared with the level the caller authenticated at. On HTTP `/sql`, the `Surreal-NS` / `Surreal-DB` headers set it independently of the credentials. Over WebSocket `/rpc`, the `use` method set it unconditionally. A query-time scope check existed, but it applied only to record users, so namespace- and database-level users were never checked. 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.\n\nThe same root cause was reported through several paths, each published as its own advisory and all fixed in 3.3.0:\n\n- [GHSA-2v9j-645m-pcrq](https://github.com/surrealdb/surrealdb/security/advisories/GHSA-2v9j-645m-pcrq): the `USE` statement\n- [GHSA-vx2p-7hhm-wv62](https://github.com/surrealdb/surrealdb/security/advisories/GHSA-vx2p-7hhm-wv62): the `Surreal-NS` / `Surreal-DB` headers with Basic authentication\n- [GHSA-3vw5-j55x-486h](https://github.com/surrealdb/surrealdb/security/advisories/GHSA-3vw5-j55x-486h): `RETURN … FETCH`, for record users\n\n### Impact\n\nWhat an attacker **can** do:\n\n- With a database- or namespace-level user in any one tenant, select another tenant through the `Surreal-NS` / `Surreal-DB` headers or the RPC `use` method. They can then read, create, update, and delete rows in its tables whose `PERMISSIONS` allow the operation, such as `PERMISSIONS FULL`.\n- Read the value of a `DEFINE PARAM` in that tenant under the same conditions.\n\nWhat it **can't** do:\n\n- Reach any tenant without valid credentials for some namespace/database on the instance. This is not an unauthenticated bypass.\n- Read or write a table whose relevant `PERMISSIONS` clause denies the operation, including `PERMISSIONS NONE` (the `DEFINE TABLE` default).\n- Pass IAM-gated operations such as `INFO FOR DB`, or change roles.\n- Affect single-tenant deployments, or callers that already hold instance-wide (root) scope.\n\n### Patches\n\nA 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`.\n\nThe 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.\n\n- Versions 3.3.0 and later are not affected by this issue.\n\n### Workarounds\n\nUsers unable to patch should consider the following workarounds:\n\n- 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.\n- 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.\n\n### References\n\n- [SurrealQL Documentation — USE](https://surrealdb.com/docs/surrealql/statements/use)\n- [SurrealQL Documentation — DEFINE TABLE … PERMISSIONS](https://surrealdb.com/docs/surrealql/statements/define/table)\n- [SurrealDB Documentation — Security and authentication](https://surrealdb.com/docs/surrealdb/security/authentication)\n- `fix(core): enforce tenant boundary on USE / process_use` (included in SurrealDB 3.3.0)\n- `fix(server): confine Surreal-NS/Surreal-DB header context to the auth level` (included in SurrealDB 3.3.0)\n- `fix(core): confine record users to their own tenant on the write path` (included in SurrealDB 3.3.0)\n- `fix(doc): re-verify record-auth namespace/database scope in the document pipeline` (included in SurrealDB 3.3.0)\n\n### Acknowledgements\n\nThank you to [thaidn](https://github.com/thaidn) for reporting this issue.\n\n### Credits\n\n- Reported by Calif.io, in collaboration with Anthropic.\n","categories":["Unclassified"],"product":"surrealdb","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/surrealdb/surrealdb/security/advisories/GHSA-w5v9-jc5f-5rmc","source_modified_at":"2026-09-28T11:15:19Z","fetched_at":"2026-10-23T20:37:03.234832Z","package":{"ecosystem":"rust","name":"surrealdb"},"range":"< 3.3.0"}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/surrealdb/surrealdb/security/advisories/GHSA-w5v9-jc5f-5rmc","source_modified_at":"2026-09-28T11:15:19Z","fetched_at":"2026-10-23T20:37:03.234832Z","package":{"ecosystem":"rust","name":"surrealdb"},"version":"3.3.0"}],"cvss":9.6,"severity":"Critical","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-09-28T11:15:19Z","modified_at":"2026-09-28T11:15:19Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/surrealdb/surrealdb/security/advisories/GHSA-w5v9-jc5f-5rmc","fetched_at":"2026-10-23T20:37:03.234832Z","source_modified_at":"2026-09-28T11:15:19Z"}],"sources":["GitHub Advisory Database"],"references":[],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":null,"confidence":"unknown","reviewed":false},"change_timestamp":"2026-09-28T11:15:19Z","content_hash":"e57ff8d394db5c0c790248f602b35194493c83b87fc49518e002e3550119318c"}}
