Sep 5, 2026·6 min read·21 visits
An authenticated SurrealDB user with minimal privileges can access and execute custom APIs defined by other tenants in multi-tenant environments, leading to unauthorized read/write access to arbitrary database resources.
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.
SurrealDB provides an architecture that allows developers to define custom HTTP API endpoints. These endpoints map direct external web requests to internal SurrealQL execution scripts. This mapping is defined via DEFINE API statements, which designate a custom route and associated queries.
By design, these custom API handlers execute with definer's rights, meaning traditional table-level and record-level permissions are bypassed during their execution to allow the engine to process specialized transactions. Because the script runs with permissions disabled, verifying the authentication and authorization scope of the caller before dispatching to the script is critical.
The attack surface exists at the routing boundary where HTTP requests targeting /api/{namespace}/{database}/{endpoint} are parsed. In multi-tenant environments, a failure to restrict users to their assigned namespace and database scopes allows low-privileged actors from one tenant context to manipulate other tenants' data stores via custom API execution.
The core flaw is a failure in authorization boundary enforcement combined with request-driven session pollution. When an HTTP request is made to a custom API route, the routing framework extracts the target namespace (ns) and database (db) parameters directly from the URL path.
Prior to the patch, the HTTP server overrode the active session state's namespace and database parameters with the user-supplied values from the request URL. While the server verified that the user's cryptographic token (such as a JWT) was valid, it omitted the step of verifying whether the authenticated security principal had authorization to operate within the targeted namespace and database.
This gap allowed an authenticated session associated with tenant_a to target the endpoint namespace and database belonging to tenant_b. Once the session context was overwritten, the engine proceeded to look up and execute the custom API endpoint configured under tenant_b. Because the custom API executed with definer's rights, the engine completed the database queries on behalf of the attacker, completely bypassing the isolation boundary.
The vulnerability was mitigated through patches implemented in commits 0938f88d196dc4eb11a82af343df3fffe9c195e2 and 75b7154f84904d047619b5a47b08d256254dceca. The solution introduces a structured authorization check, can_access_ns_db, which validates the authenticated level against the target resource parameters.
// surrealdb/core/src/iam/auth.rs
impl Auth {
/// Check whether the authenticated level is permitted to operate within the
/// given namespace and database.
pub fn can_access_ns_db(&self, ns: &str, db: &str) -> bool {
match self.level() {
Level::Root => true,
Level::Namespace(n) => n.eq(ns),
Level::Database(n, d) => n.eq(ns) && d.eq(db),
Level::Record(n, d, _) => n.eq(ns) && d.eq(db),
Level::No => true,
}
}
}This helper is placed at the critical chokepoint in the API request processor to intercept calls before execution occurs:
// surrealdb/core/src/api/invocation.rs
pub async fn process_api_request_with_stack(
api: &ApiDefinition,
req: ApiRequest,
) -> Result<ApiResponse> {
// Tenant-boundary enforcement (GHSA-848m-r628-vrxw)
let (ns_name, db_name) = opt.ns_db()?;
if !opt.auth.can_access_ns_db(ns_name, db_name) {
trace!(
request_id = %req.request_id,
"API request denied: selected namespace/database is outside the authenticated session scope"
);
return Ok(ApiResponse::from_error(ApiError::PermissionDenied, req.request_id.clone()));
}
// ... execution continues only if authorized
}A matching block was added to the datastore routing level in surrealdb/core/src/kvs/ds.rs to secure direct database routing over HTTP. These boundary checks ensure that even if route parsing overwrites session variables, the security context level acts as the authoritative boundary constraint.
An attacker can exploit this vulnerability through two separate vectors: direct HTTP custom API calls and the SQL api::invoke routine. The execution mechanics depend on the attacker having a valid authenticated session on any namespace in the system.
In a direct HTTP attack, the attacker generates a JWT for their legitimate low-privileged account within namespace_attacker. The attacker then crafts an HTTP request targeting the custom endpoint configured in namespace_victim:
GET /api/namespace_victim/database_victim/secret_endpoint HTTP/1.1
Host: target-surrealdb-instance:8000
Authorization: Bearer <attacker_jwt_token_for_namespace_attacker>The server receives the request, parses the URL, and updates the connection session namespace to namespace_victim and database to database_victim. The security layer validates that the token is authentic. In unpatched versions, the request is passed directly to the executor, which processes the custom API and returns the victim's data to the attacker.
In the SQL attack path, the attacker establishes an active database session under their own scope and calls the api::invoke function while attempting to target the victim's namespace context:
USE NS namespace_victim DB database_victim;
RETURN api::invoke("/secret_endpoint");Because the database session environment is mutated prior to the api::invoke validation, the engine processes the API call using the victim's scope parameters, allowing the attacker to retrieve data.
The impact of this vulnerability is critical in multi-tenant installations of SurrealDB. It completely breaks tenant isolation, which is a foundational requirement for Cloud and Software-as-a-Service (SaaS) environments where database instances are shared among multiple clients.
Because custom APIs run with definer's rights, an attacker does not need read or write permissions to the underlying tables of the victim database. Instead, they gain access to whatever capabilities the custom API endpoint itself exposes. If a victim has defined endpoints to create, modify, or delete records, the attacker can leverage these capabilities to perform unauthorized actions.
The CVSS v4.0 rating is 8.6 (High), with high confidentiality and high integrity impact scores. There is no direct availability impact on the database daemon, and the scope remains unchanged as the target is confined to the database instance itself.
The primary remediation strategy is upgrading the SurrealDB engine to version 3.2.0 or newer. This version implements robust validation of session levels against requested resources.
If upgrading is not immediately possible, organizations should apply the following defensive workarounds:
PERMISSIONS FULL unless manual identity checks are integrated into the custom SQL script.$auth within the endpoint scripts to verify that the calling identity is authorized to access the requested tenant resources.CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
SurrealDB SurrealDB | < 3.2.0 | 3.2.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-639: Authorization Bypass Through User-Controlled Key |
| Attack Vector | Network |
| CVSS v4.0 Score | 8.6 (High) |
| EPSS Score | 0.00367 (Percentile: 29.78%) |
| Exploit Status | PoC (Proof of Concept documented in integration tests) |
| CISA KEV Status | Not Listed |
| Vulnerability Class | Improper Authorization |
The system fails to check if an authenticated user possesses the authority to perform operations on a targeted database resource identified by a user-supplied key in the request URL.
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.