CVE-2026-14160 Overview
CVE-2026-14160 is a time-of-check to time-of-use (TOCTOU) race condition [CWE-367] in Samsung's Open Source Escargot JavaScript engine. The flaw affects Escargot commit bab3a5797557014ce3c2e28419a6310cfba90d0d and stems from insufficient revalidation of ArrayBuffer state between bounds checking and memory access in Atomics operations. An attacker with local access can leverage the race window to trigger out-of-bounds access against a detached or resized buffer. Successful exploitation impacts confidentiality, integrity, and availability of the embedding application.
Critical Impact
Local attackers can exploit the TOCTOU window in Atomics operations to force out-of-bounds reads or writes against a detached ArrayBuffer, corrupting engine memory in applications embedding Escargot.
Affected Products
- Samsung Open Source Escargot JavaScript engine
- Escargot commit bab3a5797557014ce3c2e28419a6310cfba90d0d
- Applications and devices embedding the affected Escargot revision
Discovery Timeline
- 2026-06-30 - CVE-2026-14160 published to NVD
- 2026-06-30 - Last updated in NVD database
Technical Details for CVE-2026-14160
Vulnerability Analysis
Escargot is a lightweight JavaScript engine developed by Samsung for resource-constrained environments. The vulnerability resides in the implementation of the Atomics built-ins in src/builtins/BuiltinAtomics.cpp and in the value accessors of ArrayBufferObject. During an atomic operation, the engine validates the buffer's attached state and index bounds, then coerces JavaScript arguments through operations that may invoke user-defined valueOf callbacks. Attacker-controlled JavaScript executed during coercion can detach or resize the underlying ArrayBuffer before the engine performs the actual memory access.
Root Cause
The engine performed bounds and detachment checks only once at the top of atomic operations. Subsequent argument coercion could re-enter the interpreter and mutate buffer state, but the engine did not revalidate before dereferencing the raw data pointer. In release builds, the ArrayBufferObject::getValueFromBuffer path relied on ASSERT macros for detachment and bounds validation, which are compiled out and provided no runtime protection.
Attack Vector
Exploitation requires the ability to execute JavaScript in an application that embeds the vulnerable Escargot build. The attacker crafts a script that invokes an Atomics method with an object whose valueOf handler detaches or shrinks the target ArrayBuffer mid-operation, producing an out-of-bounds read or write on a stale pointer.
// Patch: src/builtins/BuiltinAtomics.cpp
return (static_cast<size_t>(accessIndex) * elementSize) + offset;
}
+// Revalidate atomic access after potential user code execution (valueOf, etc.)
+// This prevents OOB access if the buffer was detached or resized during coercion
+static void revalidateAtomicAccess(ExecutionState& state, ArrayBuffer* buffer, size_t indexedPosition, size_t elementSize)
+{
+ // Check if buffer is detached
+ if (buffer->isDetachedBuffer()) {
+ ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "ArrayBuffer is detached");
+ }
+
+ // Re-check bounds against current buffer length
+ if (UNLIKELY(indexedPosition + elementSize > buffer->byteLength())) {
+ ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, ErrorObject::Messages::GlobalObject_RangeError);
+ }
+}
+
template <typename T>
static T atomicOperation(volatile uint8_t* rawStart, int64_t v, AtomicBinaryOps op)
{
// Source: https://github.com/Samsung/escargot/commit/9e8084ecc2f68e8584d389414c3f37fda12dab7d
A companion change in src/runtime/ArrayBufferObject.cpp promotes debug-only assertions into runtime checks, ensuring detached buffers and out-of-bounds indices raise TypeError or RangeError even in release builds:
Value ArrayBufferObject::getValueFromBuffer(ExecutionState& state, size_t byteindex, TypedArrayType type, bool isLittleEndian)
{
- ASSERT(byteLength());
+ // Always check for detached buffer (not just in debug builds)
+ if (UNLIKELY(isDetachedBuffer())) {
+ ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "ArrayBuffer is detached");
+ }
+
size_t elemSize = TypedArrayHelper::elementSize(type);
- ASSERT(byteindex + elemSize <= byteLength());
+ if (UNLIKELY(byteindex + elemSize > byteLength())) {
+ ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid byte index in getValueFromBuffer");
+ }
uint8_t* rawStart = data() + byteindex;
// Source: https://github.com/Samsung/escargot/commit/9e8084ecc2f68e8584d389414c3f37fda12dab7d
Detection Methods for CVE-2026-14160
Indicators of Compromise
- Escargot-based processes crashing with signals indicative of memory corruption during Atomics calls
- JavaScript workloads that repeatedly invoke Atomics.add, Atomics.store, or related methods with objects defining custom valueOf handlers
- Runtime errors referencing detached ArrayBuffer or invalid byte index after deploying the patched build
Detection Strategies
- Inventory embedded JavaScript runtimes and compare linked Escargot commit hashes against the vulnerable revision bab3a5797557014ce3c2e28419a6310cfba90d0d
- Enable core dump collection on devices running Escargot and inspect crashes touching ArrayBufferObject::getValueFromBuffer or BuiltinAtomics symbols
- Perform static analysis on locally executed JavaScript for patterns that combine Atomics calls with objects overriding valueOf or Symbol.toPrimitive
Monitoring Recommendations
- Log and alert on unexpected termination of processes that host the Escargot runtime
- Track file integrity of Escargot binaries and shared libraries deployed to endpoints and IoT devices
- Correlate abnormal JavaScript execution telemetry with subsequent process crashes to surface race-window exploitation attempts
How to Mitigate CVE-2026-14160
Immediate Actions Required
- Rebuild and redeploy Escargot from a commit that includes the fix in Samsung Escargot commit 9e8084e
- Audit downstream products and firmware images that vendor Escargot to confirm they ship the patched revision
- Restrict execution of untrusted JavaScript in applications embedding a vulnerable Escargot build until patched
Patch Information
The upstream fix introduces a revalidateAtomicAccess helper that re-checks buffer detachment and bounds after any coercion that may execute user JavaScript. It also converts ASSERT-based validation in ArrayBufferObject::getValueFromBuffer into runtime checks that throw TypeError on detached buffers and RangeError on out-of-bounds byte indices. Refer to the GitHub commit for the complete diff.
Workarounds
- Disable or gate features that permit execution of attacker-supplied JavaScript within Escargot-hosted applications
- Where feasible, remove or restrict access to Atomics and SharedArrayBuffer APIs at the embedder level
- Enforce least-privilege execution contexts so a compromised Escargot process cannot pivot to sensitive resources
# Verify the deployed Escargot revision includes the fix commit
git -C /path/to/escargot log --oneline | grep 9e8084ecc2f68e8584d389414c3f37fda12dab7d
# Rebuild Escargot from a patched checkout
git -C /path/to/escargot fetch origin
git -C /path/to/escargot checkout 9e8084ecc2f68e8584d389414c3f37fda12dab7d
cmake -S /path/to/escargot -B /path/to/escargot/build -DESCARGOT_MODE=release
cmake --build /path/to/escargot/build --parallel
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

