PT-2026-57501 · Crates.Io · Surrealdb
Published
2026-07-01
·
Updated
2026-07-01
CVSS v3.1
4.3
Medium
| Vector | AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N |
A record user could learn the value of a hidden field by counting how many records match a guess.
When
DEFINE FIELD ... PERMISSIONS FOR select WHERE ... hides a field's contents from a caller, and that field is indexed, running SELECT count() FROM t WHERE hidden field = "guess" GROUP ALL returned a count greater than zero whenever a record actually had that value — even though the caller was never allowed to read the field directly. The query planner used an indexed-COUNT shortcut (Index::Count, IndexCountScan, or the legacy Iterate Index Count / Iterate Index Keys paths) that counts matching index entries and skips the permission check that would normally hide the value. The same query with WITH NOINDEX correctly returned [], confirming the gap.By repeating the count query with different guesses, an attacker can confirm or recover the contents of any restricted field they could not read through a normal
SELECT.Impact
What an attacker can do:
- Confirm or recover values of a field protected by field-level SELECT permissions on any table they hold table-level SELECT on, provided the field is indexed.
- Repeat the query with different guesses to read restricted field contents one value at a time.
What it can't do:
- Read fields that are not indexed (the shortcut only fires when an index covers the predicate column).
- Cross table, database or namespace isolation boundaries.
- Modify data, escalate privileges, or affect availability.
Patches
The legacy planner (
surrealdb/core/src/idx/planner/tree.rs) and the streaming planner (surrealdb/core/src/exec/planner/select/mod.rs) now both refuse the indexed fast path when the WHERE / ORDER tree references a field governed by a non-Full SELECT permission:resolve indexesskips any B-tree / unique index whose columns are governed by such a permission.- A new
cond touches restricted fieldflag is propagated;eval countrefuses a dedicatedIndex::Countwhen set. - The streaming planner adds
cond touches restricted select field, aRestrictedIdiomCheckervisitor that matches each idiom against the table's field-permission prefixes (loaded via the plan-time txn), and gatesIndexCountScanemission on it. - The fast paths are preserved for root / owner sessions via
should check perms for view.
Versions 3.1.0 and later are not affected.
Workarounds
Users unable to patch are advised to consider the following workarounds:
- Avoid
DEFINE INDEXon fields whose values are protected by field-level SELECT permissions. The class of attack is specific to the indexed fast paths. - Restrict the ability of record users to issue arbitrary
SELECT count() … GROUP ALLqueries against tables containing field-protected columns. - Use namespace / database isolation as the primary boundary where feasible.
Fix
Incorrect Authorization
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Surrealdb