CVE-2025-69654 Overview
A denial of service vulnerability exists in QuickJS, an embeddable JavaScript engine. A crafted JavaScript input executed with the QuickJS release 2025-09-13 using the qjs interpreter with the -m option and a low memory limit can cause an out-of-memory condition followed by an assertion failure in JS_FreeRuntime (list_empty(&rt->gc_obj_list)) during runtime cleanup. Although the engine reports an OOM error, it subsequently aborts with SIGABRT because the GC object list is not fully released, resulting in a denial of service condition.
Critical Impact
Attackers can crash QuickJS interpreter instances by triggering memory exhaustion conditions that lead to improper runtime cleanup, causing service disruption for applications relying on this JavaScript engine.
Affected Products
- QuickJS release 2025-09-13 (prior to commit fcd33c1afa7b3028531f53cd1190a3877454f6b3)
- Applications embedding QuickJS with memory-constrained configurations
- Systems using qjs interpreter with the -m module option
Discovery Timeline
- 2025-12-11 - Fix committed in QuickJS repository (commit fcd33c1afa7b3028531f53cd1190a3877454f6b3)
- 2026-03-06 - CVE CVE-2025-69654 published to NVD
- 2026-03-12 - Last updated in NVD database
Technical Details for CVE-2025-69654
Vulnerability Analysis
This vulnerability falls under CWE-400 (Uncontrolled Resource Consumption) and manifests as a resource exhaustion issue within the QuickJS JavaScript engine's garbage collection mechanism. When the interpreter encounters an out-of-memory condition during execution, the subsequent runtime cleanup process fails to properly release all objects from the garbage collection object list.
The core issue occurs during the JS_FreeRuntime function execution, where an assertion check verifies that the GC object list (rt->gc_obj_list) is empty before completing runtime cleanup. Under specific memory-constrained scenarios triggered by crafted JavaScript input, this assertion fails because memory exhaustion prevents the normal cleanup sequence from completing properly.
This vulnerability is exploitable over the network without authentication or user interaction, making it particularly concerning for server-side JavaScript execution environments or web applications that evaluate untrusted JavaScript code.
Root Cause
The root cause lies in QuickJS's improper handling of memory exhaustion scenarios during runtime cleanup. When an OOM (Out-of-Memory) condition occurs, the engine correctly detects and reports the error. However, the subsequent cleanup phase in JS_FreeRuntime expects the garbage collector object list to be fully cleared before the assertion check. Under memory pressure conditions, some objects remain on the GC list, causing the list_empty(&rt->gc_obj_list) assertion to fail and the process to abort with SIGABRT.
The vulnerability was specifically triggered when using the -m option (module mode) with a low memory limit configured, suggesting the module loading pathway has different memory allocation patterns that exacerbate the issue.
Attack Vector
The attack vector is network-based, allowing remote exploitation without requiring authentication or user interaction. An attacker can exploit this vulnerability by:
- Crafting malicious JavaScript code designed to rapidly consume available memory
- Targeting QuickJS instances configured with memory limits (a common security practice)
- Sending the payload to any service that evaluates JavaScript using the vulnerable QuickJS version
- Triggering the OOM condition followed by the assertion failure during cleanup
The vulnerability requires the target to be using the module execution mode (-m flag) and have memory constraints configured, which is paradoxically a security measure intended to limit resource usage.
For technical details on the vulnerability mechanism, see the GitHub Issue Discussion where the issue was reported and tracked.
Detection Methods for CVE-2025-69654
Indicators of Compromise
- Unexpected SIGABRT signals from QuickJS interpreter processes
- Process crash logs indicating assertion failures in JS_FreeRuntime function
- Application logs showing OOM errors immediately followed by process termination
- Core dump files containing list_empty(&rt->gc_obj_list) assertion messages
Detection Strategies
- Monitor for abnormal termination of QuickJS processes with SIGABRT exit codes
- Implement logging around JavaScript evaluation calls to capture pre-crash execution context
- Deploy application performance monitoring to detect memory exhaustion patterns
- Review system logs for repeated QuickJS crashes that may indicate exploitation attempts
Monitoring Recommendations
- Set up alerting for QuickJS process crashes with assertion failure signatures
- Monitor memory usage patterns of applications embedding QuickJS for unusual spikes
- Track the frequency of OOM events in JavaScript execution contexts
- Implement centralized logging for all QuickJS-related process terminations
How to Mitigate CVE-2025-69654
Immediate Actions Required
- Update QuickJS to a version containing commit fcd33c1afa7b3028531f53cd1190a3877454f6b3 or later
- Review applications that embed QuickJS and plan upgrade paths
- Consider implementing process isolation for JavaScript execution to contain crashes
- Evaluate input validation for JavaScript code submitted to QuickJS interpreters
Patch Information
The vulnerability was fixed in commit fcd33c1afa7b3028531f53cd1190a3877454f6b3 dated 2025-12-11. Organizations should update their QuickJS installations to any version released after this commit. The fix addresses the improper cleanup sequence in JS_FreeRuntime to ensure the garbage collection object list is properly handled even during memory exhaustion scenarios.
For additional details, refer to the QuickJS GitHub Issue #468.
Workarounds
- Run QuickJS interpreter processes in isolated containers or sandboxes to limit crash impact
- Implement process restart mechanisms to automatically recover from crashes
- Add rate limiting on JavaScript execution requests to reduce denial of service impact
- Consider using process pools to ensure service availability despite individual process crashes
# Configuration example: Running QuickJS in isolated container with auto-restart
# Docker compose configuration for resilient QuickJS deployment
# Ensure using patched version: commit fcd33c1afa7b3028531f53cd1190a3877454f6b3 or later
docker run --restart=unless-stopped \
--memory=512m \
--cpus=1 \
quickjs-patched:latest
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


