CVE-2026-33943
Description
Happy DOM is a JavaScript implementation of a web browser without its graphical user interface. In versions 15.10.0 through 20.8.7, a code injection vulnerability in ECMAScriptModuleCompiler allows an attacker to achieve Remote Code Execution (RCE) by injecting arbitrary JavaScript expressions inside export { } declarations in ES module scripts processed by happy-dom. The compiler directly interpolates unsanitized content into generated code as an executable expression, and the quote filter does not strip backticks, allowing template literal-based payloads to bypass sanitization. Version 20.8.8 fixes the issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
happy-domnpm | >= 15.10.0, < 20.8.8 | 20.8.8 |
Affected products
1Patches
15437fdf8f13afix: [#2113] Fixes issue where export names can be interpolated as executable code in ESM (#2113)
2 files changed · +18 −1
packages/happy-dom/src/module/ECMAScriptModuleCompiler.ts+6 −1 modified@@ -56,6 +56,11 @@ const SYNTAX_REGEXP = /(\/)|(\(|\))|({|})|(\[|\])|(\${)|(`)|(')|(")|(\n)/gm; */ const IMPORT_REGEXP = /{([^}]+)}|\*\s+as\s+([a-zA-Z0-9-_$]+)|([a-zA-Z0-9-_$]+)/gm; +/** + * Strip invalid variable name characters regexp. + */ +const VALID_VARIABLE_NAME_REGEXP = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/; + /** * Valid preceding token before a statement. */ @@ -377,7 +382,7 @@ export default class ECMAScriptModuleCompiler { const nameParts = part.trim().split(/\s+as\s+/); const exportName = (nameParts[1] || nameParts[0]).replace(/["']/g, ''); const importName = nameParts[0].replace(/["']/g, ''); - if (exportName && importName) { + if (exportName && importName && VALID_VARIABLE_NAME_REGEXP.test(importName)) { exportCode.push(`$happy_dom.exports['${exportName}'] = ${importName}`); } }
packages/happy-dom/test/module/ECMAScriptModuleCompiler.test.ts+12 −0 modified@@ -773,6 +773,18 @@ $happy_dom.exports['string6'] = string6; }`); }); + it('Unsanitized export names are not interpolated as executable code (GHSA-6q6h-j7hj-3r64)', () => { + const code = `export { require('child_process').execSync('id') }`; + + const compiler = new ECMAScriptModuleCompiler(window); + const result = compiler.compile('http://localhost:8080/js/app/main.js', code); + + expect(result.imports).toEqual([]); + + expect(result.execute.toString()).toBe(`async function anonymous($happy_dom) { +}`); + }); + it('Handles tabs as whitespace.', () => { const code = ` function warn(...args) {
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/capricorn86/happy-dom/commit/5437fdf8f13adb9590f9f52616d9f69c3ee8db3cnvdPatchWEB
- github.com/capricorn86/happy-dom/security/advisories/GHSA-6q6h-j7hj-3r64nvdExploitVendor AdvisoryWEB
- github.com/advisories/GHSA-6q6h-j7hj-3r64ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-33943ghsaADVISORY
- github.com/capricorn86/happy-dom/releases/tag/v20.8.8nvdProductRelease NotesWEB
News mentions
0No linked articles in our index yet.