GitHub Advisoryadvisory · crates.io

GHSA-hv6h-hc26-q48p SurrealDB: Field-level SELECT permissions bypassed via graph and reference traversals

MEDIUM Published 2026-06-19 Modified 2026-09-04 Official page ↗
Aliases
CVE-2026-63738
Ecosystem
crates.io
Packages
surrealdb
Severity
Moderate
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Weaknesses
CWE-863
Reviewed
2026-06-19

Affected packages

• crates.io surrealdb: >= 3.1.0, < 3.1.5 → fixed in 3.1.5

Description

A record user could read field values hidden from them by field-level SELECT permissions by reaching the records through a graph-edge (`->`) or back-reference (`(SELECT * FROM knows)`, `person:bobknows->(SELECT * FROM person)` — returned it intact. The 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. Impact A 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. The 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). Table-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. Patches `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. Versions 3.1.5 and later are not affected. Workarounds • Force the unaffected legacy executor with `--planner-strategy compute-only` (env `SURREAL_PLANNER_STRATEGY`). • 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. • Use namespace / database isolation as the primary boundary where feasible. Resources • SurrealQL Documentation — DEFINE FIELD • SurrealQL Documentation — DEFINE TABLE … PERMISSIONS • SurrealQL Documentation — Graph relationships • `fix(exec): apply field-level SELECT permissions + computed fields when graph/reference traversals materialize full records`

Related

Alias · CVE (1)

  • CVE-2026-63738 SurrealDB versions 3.1.0 before 3.1.5 fail to enforce field-level SELECT permissions when records are accessed through graph-edge or… vulnerability

Weakness · CWE (1)

  • CWE-863 Incorrect Authorization weakness

References