CVE-2026-121417 in SurrealDB
Summary
by MITRE • 11/03/2026
SurrealDB before 3.3.0 contains a use-after-free vulnerability in surrealdb-core KV backends that pass borrowed transaction state into affinitypool::spawn_local closures relying on future Drop for safety. Rust embedders that leak a dispatched future (e.g. via mem::forget) and drop the transaction cause pool workers to read and write freed memory, risking crashes or memory corruption.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 11/03/2026
The vulnerability identified in SurrealDB versions prior to 3.3.0 represents a critical memory safety issue rooted in Rust’s ownership model being circumvented through improper future handling within key-value storage backends. The core of the flaw lies in how transaction state is managed when passed into affinitypool::spawn_local closures. In this context, the code relies on the Drop trait implementation to ensure that borrowed references remain valid for the duration of the asynchronous operation. However, if an embedder utilizing SurrealDB leaks a dispatched future by calling mem::forget or otherwise preventing its normal completion and drop sequence, the transaction state associated with that future may be dropped prematurely while background workers are still attempting to access it. This creates a classic use-after-free scenario where memory previously allocated for transaction metadata is deallocated but subsequently accessed by pool worker threads executing pending tasks.
From a technical perspective, this flaw exploits the asynchronous execution model inherent in Rust’s tokio runtime and similar async runtimes used within SurrealDB. When futures are spawned into an affinity pool, they capture references to local variables such as transaction handles or database connections. Normally, these references remain valid because the future holds them until completion. But if the original scope drops the transaction object while a leaked future still retains a reference to it, the underlying memory is freed according to Rust’s drop semantics. The background workers then operate on dangling pointers, leading to undefined behavior that can manifest as application crashes, data corruption, or potentially exploitable conditions depending on how the freed memory is reallocated and used by subsequent operations.
The operational impact of this vulnerability extends beyond simple stability issues. Memory corruption resulting from use-after-free bugs can lead to arbitrary code execution if an attacker can control the contents of the freed memory region through carefully crafted inputs that trigger specific allocation patterns before the transaction drop occurs. While Rust’s type system generally prevents many such errors, edge cases involving unsafe blocks or external FFI boundaries like those found in database engines remain susceptible when safety guarantees are bypassed via mem::forget or similar mechanisms. For organizations running SurrealDB as a service or embedded component, this could result in denial of service through repeated crashes or more severe compromise if the memory corruption is leveraged to execute malicious payloads within the process context hosting the database engine.
This vulnerability aligns with CWE-416 Use After Free and falls under MITRE ATT&CK technique T1203 Exploitation for Defense Evasion when used in conjunction with other techniques to maintain persistence or escalate privileges through memory corruption. It also relates to CWE-755 Improper Handling of Exceptional Conditions since the error handling path fails to account for futures that do not complete normally due to being forgotten by callers. The root cause stems from insufficient validation of future lifecycle management within the affinity pool implementation, particularly regarding borrow checker enforcement across async boundaries where drop order becomes non-deterministic under certain leak scenarios.
Mitigation strategies primarily involve upgrading to SurrealDB version 3.3.0 or later where this issue has been addressed by enforcing stricter lifetime constraints on transaction states passed into asynchronous closures. Developers integrating SurrealDB should audit their code for any instances of mem::forget applied to futures spawned from database operations and ensure that all dispatched tasks are properly awaited or cancelled before dropping associated resources. Additionally, enabling AddressSanitizer during testing phases can help detect similar memory safety violations early in the development lifecycle. For production environments, implementing runtime checks around transaction disposal and ensuring that no external code retains references to internal state after drop is recommended as a defensive programming practice even beyond this specific fix.