Jun 20, 2026·8 min read·1 visit
SurrealDB's query planner prematurely optimizes sorting via indexes on restricted fields before enforcing permission boundaries. An unauthorized user can query a restricted field with an ORDER BY clause, causing the database to sort the rows by the hidden values before replacing them with null. By observing the returned row sequence relative to user-controlled records, an attacker can construct a binary search oracle to extract confidential data.
SurrealDB versions 3.0.0 through 3.1.4 contain an information exposure vulnerability (CWE-203) where the query planner optimizes sorted queries using indexes on fields with field-level SELECT restrictions. Because the query planner performs index-based sorting before enforcing permission-based redaction, unauthorized users can observe the physical order of returned rows to deduce the relative values of protected fields.
SurrealDB is an open-source, multi-model database engine designed for highly scalable document, graph, and relational data structures. To enforce secure multi-tenancy and fine-grained access control, the database supports field-level permissions. These permissions allow administrators to define explicit SELECT constraints on individual fields, redacting sensitive data when queried by unauthorized roles.
To optimize queries involving sorting, SurrealDB employs an index sort pushdown mechanism within its query planner. When a query contains an ORDER BY clause, the engine searches for existing indexes on the target sorting fields. If a matching index is identified, the engine uses it to fetch and traverse records directly in their pre-sorted physical order, skipping expensive post-retrieval sorting stages.
This vulnerability arises from an architectural oversight where the query planner executes the index sort pushdown regardless of the caller's field-level read permissions. Because the sorting optimization occurs at the storage engine level prior to permission evaluation, the returned row stream preserves the sorted physical order of the restricted values. Although the field values themselves are securely replaced with null in the final projection, the structural arrangement of the records remains fully sorted.
The underlying flaw resides in the order of execution within the SurrealDB query pipeline. In a secure architecture, permission boundaries must be enforced prior to any query execution step that varies structural output based on protected parameters. In the vulnerable versions of SurrealDB, the query planner assesses index availability as part of the initial planning phase, prior to executing the security filters.
When a user issues a query containing ORDER BY restricted_field, the query planner optimizes the operation by scanning the index associated with restricted_field. The storage engine walks the B-Tree structure of the index in key order, retrieving the matching record pointers sequentially. These records are then assembled into an output stream that matches the sorted order of the underlying, non-redacted keys.
Only after the records are pulled from storage in their sorted order does the pipeline pass the dataset to the projection and authorization engine. The authorization engine correctly identifies that the user lacks SELECT permissions on the sorted field and replaces the field values with null. However, because the engine does not scramble or re-sort the output array after redaction, the physical sequence of rows serves as a side-channel oracle.
To visualize the vulnerability mechanics, consider the query pipeline progression. The database processes the execution optimization and security enforcement in a sequential block that incorrectly prioritizes data fetching over access control.
As shown in the flow diagram, the security boundary is applied at the very end of the pipeline, after the sorting sequence has already been locked into the output stream. This structural alignment allows the underlying data order to bypass the security control.
The root of the issue is in the index optimization selection logic of the SurrealDB query planner. The planner evaluated the eligibility of index optimization by matching index paths with requested sort paths, without inspecting the session privileges for those paths.
Below is a conceptual representation of the vulnerable query planning logic compared with the remediated logic implemented in version 3.1.5:
// CONCEPTUAL: Vulnerable Index Optimization Logic
fn optimize_order_by(
ctx: &Context,
query: &Query,
index: &IndexDefinition
) -> Result<bool, Error> {
// VULNERABILITY: The planner only verifies if the index matches the sort field.
// No check is executed to ensure the session user has permissions to read the field.
if query.order_by.field == index.field {
return Ok(true); // Index-driven sorting is approved prematurely
}
Ok(false)
}In the patched version, the planner was modified to verify field privileges before validating the optimization path. If the current security context indicates that the field is restricted, the planner denies the index pushdown:
// CONCEPTUAL: Patched Index Optimization Logic in v3.1.5
fn optimize_order_by(
ctx: &Context,
query: &Query,
index: &IndexDefinition
) -> Result<bool, Error> {
// PATCH: First check if the current user session has permissions to SELECT the field
if !ctx.permissions.can_select_field(&query.order_by.field) {
// Fall back to standard sorting; do not use index-driven sorting optimization
return Ok(false);
}
if query.order_by.field == index.field {
return Ok(true);
}
Ok(false)
}By rejecting the index-driven sorting path for restricted fields, the database engine falls back to evaluating the query without optimization. The database fetches records, redacts the values of restricted fields to null, and then attempts to sort the redacted data. Because all redacted fields are represented as identical null values at the time of sorting, the resulting sequence contains no ordering bias, eliminating the side-channel leak.
An attacker with standard table-level read privileges can construct a value-ordering oracle by utilizing their ability to insert and modify their own records within the same table. By populating the table with controlled decoy values, they can pinpoint the exact value of a redacted field belonging to a victim via binary search.
First, the attacker identifies a target field, such as ssn, which is hidden behind field-level permissions but is optimized with an index. The attacker inserts several records that they own into the target table, specifying known sequential values for the ssn field:
-- Attacker inserts controlled records with known values
CREATE secrets:attacker_low SET ssn = 100, owner = 'attacker';
CREATE secrets:attacker_mid SET ssn = 500, owner = 'attacker';
CREATE secrets:attacker_high SET ssn = 900, owner = 'attacker';The target victim record contains a sensitive, hidden value:
-- Victim record (hidden from attacker, value is 555)
CREATE secrets:victim SET ssn = 555, owner = 'victim';The attacker then runs a sorted query on the table, ordering by the hidden field:
SELECT id, ssn FROM secrets ORDER BY ssn;The engine processes this query, sorts the rows based on the actual values (100, 500, 555, 900), and then applies the redaction, resulting in the following output returned to the attacker:
[
{ "id": "secrets:attacker_low", "ssn": 100 },
{ "id": "secrets:attacker_mid", "ssn": 500 },
{ "id": "secrets:victim", "ssn": null },
{ "id": "secrets:attacker_high", "ssn": 900 }
]By inspecting the location of secrets:victim relative to their known sentinel records, the attacker deduces that the victim's ssn is bounded between 500 and 900. By continually adjusting their controlled decoy values to the midpoint of the newly calculated range, the attacker can execute an iterative binary search to discover the precise value in logarithmic time.
The security impact is a loss of data confidentiality. While the database correctly prevents direct unauthorized retrieval of protected fields, this side-channel allows attackers to bypass access control rules entirely.
In applications where sensitive numerical or lexical data—such as credit card numbers, social security numbers, salaries, or secret access tokens—is stored in indexed fields, an attacker can extract these values with absolute precision. The severity of the leak is tied to the size and density of the search space, but standard binary search math guarantees that even wide-range integers can be leaked in dozens of queries.
The CVSS score is established as 4.3 (Medium). Although the direct CVSS rating reflects low confidentiality impact because the disclosure occurs through indirect side-channels rather than standard read commands, the actual operational impact is severe. This is especially true in multi-tenant environments where shared tables house high-value corporate secrets.
The definitive remediation for this vulnerability is to upgrade SurrealDB installations to version 3.1.5 or later. In version 3.1.5, the query planner blocks optimization on fields restricted by field-level permissions, preventing structural ordering leaks.
For systems where upgrading is not immediately possible, three primary workarounds can be applied. The first workaround is to disable index optimization entirely. This can be achieved by launching the SurrealDB instance with the environment variable SURREAL_PLANNER_STRATEGY=compute-only, which forces the query engine to evaluate all query phases sequentially without planner-level index pushdowns.
The second workaround is to avoid using index definitions on fields protected by field-level permissions. If an index is not defined on the target field, the query planner cannot optimize the ORDER BY path, neutralizing the side-channel.
The third workaround is to migrate permission structures from field-level security to table-level security. When access is restricted at the table level (using DEFINE TABLE secrets PERMISSIONS FOR select WHERE owner = $auth.id), the database restricts query execution on the entire table rather than column-by-column, preventing low-privileged users from querying the table and using the sorting oracle.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
surrealdb SurrealDB | >= 3.0.0, < 3.1.5 | 3.1.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-203 (Information Exposure Through Discrepancy) |
| Attack Vector | Network (Unauthenticated or Low-Privileged SQL Access) |
| CVSS v3.1 | 4.3 (Medium) |
| Impact Type | Confidentiality / Data Exposure Side-Channel |
| Exploit Status | Conceptual / PoC |
| Remediation Status | Patched in 3.1.5 |
The database query planner utilizes sorted indexes to fulfill ORDER BY statements prior to verifying field-level select permissions. While unauthorized output values are correctly replaced with NULL, the physical sequence of rows remains sorted by the forbidden values, enabling an attacker to infer values via a binary search side-channel.
A local file disclosure vulnerability exists in SurrealDB's full-text search capabilities, allowing authenticated users with database EDITOR or OWNER roles to read arbitrary files from the host system filesystem. This occurs by abusing the mapper() filter inside a DEFINE ANALYZER statement to point to system files.
A security vulnerability exists in SurrealDB's streaming query planner where streaming graph edge traversals or reverse-reference traversals bypass field-level SELECT permissions. This vulnerability allows an authenticated database user with valid, low-privileged credentials holding table-level SELECT permissions to bypass field-level access controls and read highly confidential or restricted fields.
An authenticated denial-of-service vulnerability in SurrealDB allows remote attackers with query privileges to crash the server process. The issue arises from uncontrolled recursion during the compilation, serialization, or deallocation of exceptionally deep Abstract Syntax Trees (ASTs). While the iterative Pratt parser successfully handles long flat sequences of binary operators without triggering recursion limits, the resulting AST structure causes stack overflow in downstream recursive tree-walking components.
The local media server (mediasrv.py) in Anki up to and including version 25.09.2 fails to validate incoming HTTP requests. The server does not validate the Origin header, enabling cross-origin requests. Additionally, several endpoints suffer from directory traversal vulnerabilities. Combined, these flaws permit an unauthenticated remote attacker to exfiltrate arbitrary files from a local file system when a user visits a malicious website.
The http4k-security-digest module within the http4k library fails to validate HTTP Digest Access Authentication nonces by default. Due to an always-true nonce verifier lambda implementation, applications using default configurations do not enforce session freshness or uniqueness. This design flaw allows remote attackers to perform replay attacks, gaining unauthorized access to protected endpoints by intercepting and retransmitting valid authorization headers.
CVE-2026-11769 is a directory traversal vulnerability affecting the Grafana Operator before version 5.24.0. An authenticated attacker with basic namespace privileges can deploy a crafted GrafanaDashboard or GrafanaLibraryPanel custom resource to read sensitive local files. This enables the extraction of the service account token of the operator manager, resulting in cluster-wide privilege escalation.