Critical Security Flaw Discovered in Popular JavaScript Library Happy DOM
A serious security vulnerability has been discovered in Happy DOM, a JavaScript library widely used for server-side rendering and testing frameworks. Identified as CVE-2025-61927, this flaw enables attackers to breach the library’s virtual machine (VM) context, which could lead to remote code execution on affected systems. With millions of applications relying on Happy DOM, the implications of this vulnerability are significant.
The VM Context Escape Vulnerability Explained
The vulnerability stems from inadequate isolation in the Node.js VM context used in versions 19 and earlier of Happy DOM. Typically designed to act as a secure environment for running untrusted code, the VM context here has been compromised. This flaw allows malicious JavaScript code to escape its confined space and interact with functions at a higher system level.
Researcher Mas0nShi highlighted how this vulnerability takes advantage of JavaScript’s constructor inheritance chain. By traversing this chain from the context’s objects, attackers can access the global Function
constructor, which permits arbitrary code execution. This effectively nullifies the security intended by the VM context, allowing attackers to execute code that can alter the host system.
The nature of the attack can depend on the module system utilized—either CommonJS or ECMAScript Modules (ESM). Systems that employ CommonJS seem particularly vulnerable, as attackers can leverage the require()
function to import and execute additional modules. While ESM environments offer some restrictions, they still enable attackers to retrieve certain process-level information.
Understanding the Scope and Impact
Happy DOM is extensively utilized in server-side rendering (SSR) and testing environments that handle user-generated or untrusted HTML content. An estimated 2.7 million users rely on this library for effectively rendering and testing JavaScript applications. The applications that render dynamically user-controlled content are particularly at risk, providing a pathway for attackers to inject and execute malicious scripts.
Common attack vectors include:
- Data Exfiltration: Attackers may access sensitive information like environment variables, configuration files, or secret tokens.
- Lateral Movement: Malicious users could exploit network access within the environment to navigate across systems, despite some protections like CORS being in place.
- Code Execution: Attackers can run arbitrary commands by taking advantage of child processes.
- Persistence: File system access may allow attackers to alter or embed malicious payloads on the host system.
Technical Insights and Reproduction of the Attack
In CommonJS environments, attackers can gain access to the require()
function through the escape, allowing them to import essential Node.js modules like fs
to read files:
const { Window } = require(‘happy-dom’);
const window = new Window({ console });
window.document.write(`
const process = this.constructor.constructor(‘return process’)();
const require = process.mainModule.require;
console.log(‘Files:’, require(‘fs’).readdirSync(‘.’).slice(0,3));`);
In contrast, ECMAScript module contexts restrict module importing, but attackers can still access the process
object to obtain process-level data:
const { Window } = require(‘happy-dom’);
const window = new Window({ console });
window.document.write(`
const process = this.constructor.constructor(‘return process’)();
console.log(‘PID:’, process.pid);`);
A crucial aspect to note is that JavaScript evaluation is enabled by default in Happy DOM, a detail that may not be obvious to users. This poses substantial risks, particularly when handling untrusted code.
Recommended Action and Mitigation Strategies
The vulnerability has been addressed in Happy DOM version 20, which disables JavaScript evaluation by default. This update includes warnings for users when JavaScript evaluation is active in potentially insecure settings.
Users are strongly encouraged to upgrade to version 20 or later without delay to mitigate risks associated with this vulnerability. For those unable to upgrade immediately, it is advisable to completely disable JavaScript evaluation unless the processed content is confirmed to be fully trusted.
Additionally, users can enhance security by running Node.js with the --disallow-code-generation-from-strings
flag. This setting prevents string-based code generation methods like eval()
and Function()
from executing at the process level, thus blocking potential exploits even if JavaScript evaluation is enabled. It’s important to note that eval()
and Function()
can still be used safely within the isolated context of Happy DOM itself.