SurrealDB: Authenticated subscribers can read records hidden by SELECT permissions via LIVE subscriptions
Medium4.3Published Jul 1, 2026
A record user could read records the table's SELECT permission expression should have hidden, when that expression referenced `$value`, `$before`, `$after`, or `$event`. Binding a chosen value to that name before registering a `LIVE SELECT` caused notifications to evaluate the permission against the attacker's input instead of the real document. ### Impact A record user binds a value to `$value`, `$before`, `$after`, or `$event` (e.g. `LET $value = [$auth.id]`) and registers `LIVE SELECT * FROM person`. The captured value shadows the real document at notification time, so a SELECT permission like `WHERE $auth.id.id() IN $value` passes for every record on the table , the subscriber receives notifications for records they should not see. Read-only impact, bounded to one table. Permission expressions that reference only field names, `$auth`, or `$session` are unaffected. ### Patches A patch has been introduced that re-orders the LIVE notification parameter binding so captured user variables are added first and the trusted document-context and session parameters are added last. - Versions 3.1.0 and later are not affected by this issue. ### Workarounds Affected users who are un...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| surrealdb crates.io | < 3.1.0 | 3.1.0 |
Details and references
A record user could read records the table's SELECT permission expression should have hidden, when that expression referenced `$value`, `$before`, `$after`, or `$event`. Binding a chosen value to that name before registering a `LIVE SELECT` caused notifications to evaluate the permission against the attacker's input instead of the real document. ### Impact A record user binds a value to `$value`, `$before`, `$after`, or `$event` (e.g. `LET $value = [$auth.id]`) and registers `LIVE SELECT * FROM person`. The captured value shadows the real document at notification time, so a SELECT permission like `WHERE $auth.id.id() IN $value` passes for every record on the table , the subscriber receives notifications for records they should not see. Read-only impact, bounded to one table. Permission expressions that reference only field names, `$auth`, or `$session` are unaffected. ### Patches A patch has been introduced that re-orders the LIVE notification parameter binding so captured user variables are added first and the trusted document-context and session parameters are added last. - Versions 3.1.0 and later are not affected by this issue. ### Workarounds Affected users who are unable to update should avoid table-`PERMISSIONS` and LIVE `WHERE` expressions that read user-named variables (`$value`, `$before`, `$after`, `$event`) without also gating on a system-derived field such as the record id.
- CVSS 3.1
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
- Severity from
- GitHub (reviewed advisory)
- Weakness
- CWE-863
More SurrealDB advisories
All SurrealDB| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Jul 1 | SurrealDB: Edge PERMISSIONS FOR delete bypassed when a connected node is deleted | Medium5.4 | 3.1.0 |
| Jul 1 | SurrealDB: ES512 silently downgraded to ES384 due to jsonwebtoken crate limitation | Medium4.3 | 3.1.0 |
| Jul 1 | SurrealDB: Field-level SELECT permissions bypassed via indexed COUNT fast paths | Medium4.3 | 3.1.0 |
| Jul 1 | SurrealDB: USE NS/DB implicit creation bypasses DEFINE authorization | Medium6.5 | 3.1.0 |
| Jul 1 | SurrealDB: Port-specific --deny-net rules silently bypassed on HTTP redirect | Medium6.4 | 3.1.0 |
| Jul 1 | SurrealDB: `RELATE` overwrites existing edge records without `UPDATE` permission | Medium4.3 | 3.1.0 |