【中危】SurrealDB: Field-level SELECT permissions bypassed via graph and reference traversals
安全速报 · 严重级:中危 · CVSS:4.3 · GHSA-hv6h-hc26-q48p
漏洞概要
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 (<~) traversal instead of a direct SELECT.
When 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->(SELECT * FROM knows), person:bob<~(SELECT * FROM comment), or a projected target vertex ->knows->(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(envSURREAL_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.
References
- 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
受影响组件
| 生态 | 组件 | 受影响版本 | 修复版本 |
|---|---|---|---|
| rust | surrealdb |
>= 3.1.0, < 3.1.5 | 3.1.5 |
修复建议
升级 surrealdb 至 3.1.5 或更高版本。
参考链接
- GitHub Advisory GHSA-hv6h-hc26-q48p
- https://github.com/surrealdb/surrealdb/security/advisories/GHSA-hv6h-hc26-q48p
本文基于 GitHub Advisory Database(CC-BY-4.0 授权)整理,数据来源已注明。
评论
登录 后参与讨论。
还没有评论,来说两句。