Skip to content

SurrealDB: Graph traversal bypasses table SELECT permissions

Moderate severity GitHub Reviewed Published May 27, 2026 in surrealdb/surrealdb • Updated Jul 1, 2026

Package

cargo surrealdb (Rust)

Affected versions

< 3.1.0

Patched versions

3.1.0

Description

An authenticated record or scope user could read records on any table reachable through a graph edge or REFERENCES TO back-reference, regardless of that table's PERMISSIONS FOR select clause.

Traversing SELECT * FROM source->edge->target returned full documents from target even when target was defined as PERMISSIONS FOR select NONE. The same bypass extended through multi-hop chains, so any table reachable by a sequence of edges from a readable starting point was exposed.

The root cause: GraphEdgeScan and ReferenceScan fetched records straight from storage without routing them through Document::pluck_select, so the target table's permission expression was never consulted.

Impact

An authenticated record or scope user can read records on any table reachable through a chain of graph edges or back-references from a table they have select on, regardless of the target's PERMISSIONS FOR select clause. Confidentiality-only and bounded to the caller's current database — namespace and database isolation are unaffected.

Patches

A new per-batch permission cache (exec::permission::CachedTableSelect) resolves each target table's SELECT permission once and filters yielded values through check_permission_for_value, matching the regular SELECT code path.

  • Versions 3.1.0 and later are not affected.

Workarounds

  • Remove select permission on edge tables whose targets should be hidden.
  • Use namespace or database isolation as the primary boundary where feasible.

References

@rowan-baker rowan-baker published to surrealdb/surrealdb May 27, 2026
Published to the GitHub Advisory Database Jul 1, 2026
Reviewed Jul 1, 2026
Last updated Jul 1, 2026

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
None
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

EPSS score

Weaknesses

Exposure of Sensitive Information to an Unauthorized Actor

The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information. Learn more on MITRE.

Incorrect Authorization

The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. Learn more on MITRE.

CVE ID

No known CVE

GHSA ID

GHSA-vjjx-rfw4-rmfc

Source code

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.