{"id":"GHSA-hv6h-hc26-q48p","summary":"SurrealDB: Field-level SELECT permissions bypassed via graph and reference traversals","details":"A record user could read field values hidden from them by field-level SELECT permissions by reaching the records through a graph-edge (`-\u003e`) or back-reference (`\u003c~`) traversal instead of a direct `SELECT`.\n\nWhen a table was readable at the table level but carried a field hidden by a field-level permission (`DEFINE FIELD secret ON knows PERMISSIONS FOR select NONE`), a direct `SELECT * FROM knows` hid `secret` — but reaching the same records through a traversal that yields full objects — `person:bob-\u003e(SELECT * FROM knows)`, `person:bob\u003c~(SELECT * FROM comment)`, or a projected target vertex `-\u003eknows-\u003e(SELECT * FROM person)` — returned it intact.\n\nThe root cause: the shared `resolve_record_batch` helper used by `GraphEdgeScan` (`FullEdge`) and `ReferenceScan` (`FullRecord`) enforced only the table-level SELECT permission and pushed raw record data, never running the field-level filtering (`build_field_state` / `filter_fields_by_permission`) that ordinary table scans and `fetch_record` apply.\n\n### Impact\n\nA record user can read the values of fields hidden by field-level SELECT permissions, on tables they already hold table-level SELECT on, by materialising the records through a graph-edge, back-reference, or target-vertex traversal — recovering the values directly, for every record the traversal returns.\n\nThe disclosure is confined to the field-permission layer: it grants **no unauthorised cross-table, cross-record, or cross-namespace/database access**. The table's own SELECT permission — including any row-level `WHERE` predicate — is still enforced, so the caller only reaches records they were already entitled to read; only the per-field SELECT filtering within those records is skipped. Root and record-owner sessions are unaffected, and data cannot be modified (confidentiality only).\n\nTable-level enforcement on these traversals landed in 3.1.0 (the fix for GHSA-vjjx-rfw4-rmfc); releases before 3.1.0 additionally exposed whole records on tables the caller could not read, and are covered by that advisory.\n\n### Patches\n\n`resolve_record_batch` (the shared helper that materialises full records for graph and reference traversals) now applies field-level SELECT permissions and read-time `COMPUTED` fields to each record, matching the regular table-scan and `fetch_record` paths.\n\nVersions 3.1.5 and later are not affected.\n\n### Workarounds\n\n- Force the unaffected legacy executor with `--planner-strategy compute-only` (env `SURREAL_PLANNER_STRATEGY`).\n- Do not rely on field-level SELECT permissions to hide values on tables reachable as a graph edge, reference target, or traversal vertex; restrict at the table level instead.\n- Use namespace / database isolation as the primary boundary where feasible.\n\n### Resources\n\n- [SurrealQL Documentation — DEFINE FIELD](https://surrealdb.com/docs/surrealql/statements/define/field)\n- [SurrealQL Documentation — DEFINE TABLE … PERMISSIONS](https://surrealdb.com/docs/surrealql/statements/define/table)\n- [SurrealQL Documentation — Graph relationships](https://surrealdb.com/docs/surrealql/datamodel/relationships)\n- `fix(exec): apply field-level SELECT permissions + computed fields when graph/reference traversals materialize full records`","aliases":["CVE-2026-63738"],"modified":"2026-09-04T20:25:35.824430Z","published":"2026-06-19T22:10:53Z","database_specific":{"cwe_ids":["CWE-863"],"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2026-06-19T22:10:53Z","nvd_published_at":null},"references":[{"type":"WEB","url":"https://github.com/surrealdb/surrealdb/security/advisories/GHSA-hv6h-hc26-q48p"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-63738"},{"type":"PACKAGE","url":"https://github.com/surrealdb/surrealdb"},{"type":"WEB","url":"https://www.vulncheck.com/advisories/surrealdb-before-field-permission-bypass-via-traversal"}],"affected":[{"package":{"name":"surrealdb","ecosystem":"crates.io","purl":"pkg:cargo/surrealdb"},"ranges":[{"type":"SEMVER","events":[{"introduced":"3.1.0"},{"fixed":"3.1.5"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-hv6h-hc26-q48p/GHSA-hv6h-hc26-q48p.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N"}]}