A critical-severity vulnerability has been disclosed in Happy DOM, a popular JavaScript package used to emulate web browsers for testing, scraping, and server-side rendering (SSR). Tracked as CVE-2025-61927 and assigned a CVSSv4 score of 9.4, the flaw could allow attackers to escape the Node.js virtual machine (VM) context and execute arbitrary code on the host system.
According to the advisory, “Happy DOM v19 and lower contains a security vulnerability that puts the owner system at the risk of RCE (Remote Code Execution) attacks.”
Happy DOM is a JavaScript implementation of a web browser without a graphical user interface, designed to emulate DOM and HTML standards defined by the WHATWG. The library is widely used in test environments and SSR frameworks, with over 2.7 million downloads every week.
The issue stems from how Happy DOM handles JavaScript execution within its Node.js VM context. The project explains that “A Node.js VM Context is not an isolated environment, and if the user runs untrusted JavaScript code within the Happy DOM VM Context, it may escape the VM and get access to process level functionality.”
Essentially, the flaw allows untrusted scripts to access Node.js process-level objects, potentially leading to arbitrary code execution. Depending on the environment, attackers could use either CommonJS or ESM modules to achieve different levels of control.
“With CommonJS the attacker can get hold of the require() function to import modules,” the advisory states. With ESM it’s not possible to get hold of import or require, but attackers can still access process-level details such as process.pid.
The vulnerability originates from JavaScript’s Function inheritance chain. All classes and functions inherit from Function, which can evaluate code from strings. “By walking the constructor chain it’s possible to get hold of Function at process level,” the advisory explains. “As Function can evaluate code from strings, it’s possible to execute code at process level.”
Running Node.js with the flag –disallow-code-generation-from-strings can block this vector by disabling dynamic string-based code execution at the process level.
A simple proof of concept demonstrates the risk: