Sep 5, 2026·7 min read·2 visits
A design flaw in SurrealDB allows authenticated users to bypass read-only database permission rules, enabling unauthorized writes and data modification through nested permission queries.
An incorrect authorization vulnerability (CWE-863) in SurrealDB allows authenticated, low-privileged users to execute unauthorized state-modifying queries. This occurs because the database disabled permissions during evaluation of custom PERMISSIONS WHERE predicates to prevent infinite recursion.
SurrealDB is a multi-model database engine designed for flexible schema definitions and fine-grained access control. Users utilize Role-Based Access Control (RBAC) and record-level permissions specified inside DEFINE TABLE and DEFINE FIELD declarations. These permission policies are computed dynamically during database operations using conditions specified in the PERMISSIONS clause.
The vulnerability tracked as CVE-2026-63733 is an incorrect authorization flaw (CWE-863) within the evaluation context of SurrealDB permission predicates. Because the engine disabled database permission enforcement while processing these predicates to prevent infinite recursive authorization loops, it opened an unanticipated write-privilege escalation vector. Any query execution occurring inside a table or field permission predicate inherited this unconstrained execution state.
An authenticated database user with minimal privileges can trigger the evaluation of a guarded resource's permissions. By arranging for the permission predicate to execute a data-modifying operation, such as an INSERT or CREATE query, the user bypasses standard database boundaries. This enables unauthorized writes to restricted tables or metadata structures without administrative privileges.
The root cause lies in how SurrealDB managed the query evaluation options context to prevent infinite recursion during permission verification. In SurrealDB, verifying table or field permissions often requires executing standard SurrealQL queries. For example, verifying a user's rights to a document might require reading metadata from a relation table, which itself requires permission checks, potentially leading to infinite recursion and stack overflow.
To prevent this loop, the engine's query scheduler disabled database permissions entirely while executing permission predicates. This was achieved by creating a cloned execution options struct where the permission check parameter was explicitly flagged as false. When this modified context became active, the query optimizer bypassed all authorization steps, assuming any action performed during permission evaluation was safe.
However, the query evaluation engine did not restrict the type of statement processed inside this permission context. The parser allowed arbitrary SurrealQL statement blocks, including data-modifying operations like CREATE, UPDATE, and DELETE. Consequently, when the scheduler executed a permission predicate containing write statements, the query ran to completion with administrative-level execution privileges.
The patch resolves the privilege escalation vector through a multi-tier defense consisting of static AST inspection and dynamic runtime enforcement. At schema definition time, SurrealDB now traverses the AST of any permission predicate to check for write operations. If any write-like nodes are found during compilation, the database rejects the DEFINE or ALTER statement immediately.
The static checker utilizes the newly introduced has_direct_write function to recursively inspect query expressions:
// Post-patch AST static check implementation
pub(crate) fn has_direct_write(&self) -> bool {
match self {
// Data-modifying statements represent a direct write
Expr::Create(_)
| Expr::Update(_)
| Expr::Delete(_)
| Expr::Relate(_)
| Expr::Insert(_)
| Expr::Define(_)
| Expr::Remove(_)
| Expr::Rebuild(_)
| Expr::Upsert(_)
| Expr::Alter(_) => true,
// Combinators are checked recursively
Expr::Prefix { expr, .. }
| Expr::Postfix { expr, .. }
| Expr::Throw(expr) => expr.has_direct_write(),
Expr::Binary { left, right, .. } => left.has_direct_write() || right.has_direct_write(),
Expr::Return(s) => s.what.has_direct_write(),
Expr::Let(s) => s.what.has_direct_write(),
Expr::Block(block) => block.has_direct_write(),
_ => false,
}
}This function identifies forbidden keywords and flags them before they can be written to the schema definition store.
Because users can define custom functions which perform side-effects and are only resolved at runtime, static analysis alone is insufficient. The second defense layer introduces a new runtime boolean permission_predicate inside the query context options. When executing permission evaluations, the system initializes options via new_for_permission_predicate() instead of disabling verification completely with new_with_perms(false).
// Runtime intercept during statement execution
if opt.permission_predicate
&& matches!(
self,
Expr::Create(_)
| Expr::Update(_)
| Expr::Upsert(_)
| Expr::Delete(_)
| Expr::Relate(_)
| Expr::Insert(_)
| Expr::Define(_)
| Expr::Remove(_)
| Expr::Rebuild(_)
| Expr::Alter(_)
) {
return Err(ControlFlow::Err(anyhow::Error::new(Error::PermissionPredicateSideEffect)));
}This ensures that even if a write-enabling statement bypasses static analysis (such as through a pre-defined schema function execution), the runtime scheduler actively blocks the evaluation and returns a PermissionPredicateSideEffect error.
Exploitation of CVE-2026-63733 requires an attacker to have authenticated access to the target SurrealDB instance. The attacker must possess enough privileges to trigger a read or write operation on a table guarded by a custom permission predicate. If the schema contains a user-defined function executing mutations inside a permission clause, the attacker can execute arbitrary database writes.
A target scenario involves a database schema with an audit table and a victim table containing restricted data records. The database administrator declares a custom function fn::side_effect designed to write records to audit, but hooks it into the permission predicate for the victim table:
-- Schema setup
DEFINE TABLE audit SCHEMALESS PERMISSIONS FOR select FULL;
DEFINE FUNCTION fn::side_effect() {
CREATE audit SET marker = true;
RETURN true;
} PERMISSIONS FULL;
DEFINE TABLE victim SCHEMALESS PERMISSIONS FOR select, update WHERE fn::side_effect();When an unprivileged user signs in with standard permissions and attempts to read from the victim table, SurrealDB evaluates the authorization conditions. This evaluation invokes fn::side_effect(). Under vulnerable versions, the nested CREATE audit query runs successfully inside the permission-free thread context, registering unauthorized records.
The following Mermaid sequence diagram illustrates the lifecycle of this authorization bypass and the execution flow leading to unauthorized data modification:
The impact of this vulnerability is unauthorized data modification and privilege escalation. While SurrealDB's role-based access control models are designed to isolate customer data and lock down schema definitions, CVE-2026-63733 invalidates these security guarantees. A low-privileged tenant or compromised database user can write data, alter schema definitions, or corrupt records.
The CVSS v3.1 base score is 4.3, with a vector string of CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N. This score is constrained because exploiting the vulnerability requires low privilege (PR:L) and results in low integrity impact (I:L) under standard vulnerability grading criteria. However, in multi-tenant environments relying entirely on SurrealDB row-level permissions for data isolation, this vulnerability represents a complete breakdown of isolation barriers.
The probability of exploitation remains low, as reflected by the EPSS score of 0.00287. It is not currently included on CISA's Known Exploited Vulnerabilities (KEV) catalog, nor are there functional public exploits available. Nevertheless, the integrity risks to environments running custom schemas with dynamic evaluation logic are significant.
The primary and recommended resolution is upgrading the database deployment to SurrealDB version 3.2.0 or later. This version contains the comprehensive double-layer fix that blocks data modification queries statically and dynamically during permission evaluation.
If immediate upgrading is not possible, system administrators must inspect all custom table and field definitions for potential side-effects. This can be achieved by dumping the database schema definition using SurrealQL commands and inspecting the output:
-- Export schema to review definitions
INFO FOR DB;Identify any definitions that use user-defined functions or complex query blocks in their WHERE expressions. Replace dynamic, procedural permission logic with declarative, static filters. For example, ensure that policies are restricted to identity checks matching internal parameters (such as $auth.id == owner) rather than executing database queries.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
SurrealDB SurrealDB | < 3.2.0 | 3.2.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-863 |
| Attack Vector | Network |
| CVSS v3.1 Score | 4.3 |
| EPSS Score | 0.00287 |
| Impact | Incorrect Authorization (Integrity Bypass) |
| Exploit Status | None (No public exploit available) |
| KEV Status | Not Listed |
The software performs an authorization check when an actor attempts to access a resource or perform an action, but the check is configured or implemented incorrectly, allowing unauthorized access.
SurrealDB prior to version 3.2.0 is vulnerable to an authorization bypass where authenticated users can invoke custom API endpoints belonging to other tenants. This cross-tenant data access occurs because the system fails to validate authorization scope boundaries against request-supplied namespace and database identifiers before executing scripts with elevated definer's rights.
SiYuan before v3.7.4 fails to enforce publish-access filters on five filetree path-resolution endpoints, allowing unauthenticated attackers to reconstruct private directory layouts and map document structures.
Prior to version v3.7.4, the SiYuan personal knowledge management system contained a critical logical authorization vulnerability within its database view rendering component. The flaws allowed unauthenticated remote attackers to bypass publish-access filters on databases, exposing sensitive Relation and Rollup cell contents belonging to private or password-protected repositories.
An information disclosure vulnerability exists in SiYuan prior to v3.7.4 due to missing authorization checks on the getEncryptedNotebookStatus API endpoint, allowing unprivileged or anonymous users to enumerate protected notebooks.
An information disclosure vulnerability in the SiYuan application exposes the global session cookie signing key via the `/api/system/getConf` endpoint. This allows unauthenticated remote attackers or low-privileged users to forge administrative session cookies and gain unauthorized access to the application kernel.
CVE-2026-72795 is a critical missing authorization vulnerability (CWE-862) in SiYuan, a self-hosted personal knowledge platform. When configured in publish/read-only mode, the application fails to validate publish-access rules on dynamic child blocks transcluded via SQL queries. This allows anonymous external visitors to access hidden, password-protected, or forbidden note content.