{"schema":"threatline.record/2","record":{"id":"GHSA-3vw5-j55x-486h","aliases":["GHSA-3vw5-j55x-486h"],"summary":"Record users can read another tenant's records through RETURN … FETCH","details":"A record user scoped to one namespace/database could read a record in another namespace/database on the same instance by naming it in a `RETURN … FETCH`.\n\nA record user could select a foreign namespace/database, but ordinary table scans then refused them, because those scans checked a record user's scope. Resolving a record id through `FETCH` did not apply that check. So a record user who knew the id of a record in another tenant could read it:\n\n```surql\nUSE NS ns_b DB db_b;\nRETURN { one: post:secret } FETCH one;  -- returns post:secret from ns_b/db_b\n```\n\nTable-level and field-level `PERMISSIONS` on the fetched record were still applied, so a record in a `PERMISSIONS FULL` table was returned in full.\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-w5v9-jc5f-5rmc](https://github.com/surrealdb/surrealdb/security/advisories/GHSA-w5v9-jc5f-5rmc): the headers and the RPC `use` method, for system users\n\n### Impact\n\nWhat an attacker **can** do:\n\n- As a record user of one tenant, read a record in another tenant on the same instance, given its record id. This works when the record's table and field `PERMISSIONS` allow it to be read, such as `PERMISSIONS FULL`.\n\nWhat it **can't** do:\n\n- Discover record ids. `FETCH` resolves an id the caller names; it does not scan or list the foreign table.\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 [rexpository](https://github.com/rexpository) for reporting this issue.\n","categories":["Unclassified"],"product":"surrealdb","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/surrealdb/surrealdb/security/advisories/GHSA-3vw5-j55x-486h","source_modified_at":"2026-09-28T11:15:20Z","fetched_at":"2026-10-24T05:41:33.294140Z","package":{"ecosystem":"rust","name":"surrealdb"},"range":">= 3.0.0, < 3.3.0"}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/surrealdb/surrealdb/security/advisories/GHSA-3vw5-j55x-486h","source_modified_at":"2026-09-28T11:15:20Z","fetched_at":"2026-10-24T05:41:33.294140Z","package":{"ecosystem":"rust","name":"surrealdb"},"version":"3.3.0"}],"cvss":6.5,"severity":"Medium","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-09-28T11:15:20Z","modified_at":"2026-09-28T11:15:20Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/surrealdb/surrealdb/security/advisories/GHSA-3vw5-j55x-486h","fetched_at":"2026-10-24T05:41:33.294140Z","source_modified_at":"2026-09-28T11:15:20Z"}],"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:20Z","content_hash":"907a25dd02c22d1fd6678780b7ea4ed5c81e61123d36611e455fcac54d013fc8"}}
