Repository navigation
chore(deps): update dependency happy-dom to v21 [security] - #1342
Open
renovate[bot] wants to merge 1 commit into
Open
renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
Contributor
size-limit report 📦
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1342 +/- ##
=======================================
Coverage 90.00% 90.00%
=======================================
Files 3 3
Lines 80 80
Branches 20 20
=======================================
Hits 72 72
Misses 6 6
Partials 2 2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
March 29, 2026 16:51
40f488d to
7802511
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
April 1, 2026 18:34
7802511 to
7374a26
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
April 8, 2026 21:01
7374a26 to
6cfb329
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
April 29, 2026 18:48
6cfb329 to
48e98dd
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
2 times, most recently
from
May 18, 2026 11:50
b9c3b50 to
e3934f1
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
May 28, 2026 16:12
e3934f1 to
9e34f4d
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
June 14, 2026 23:37
9e34f4d to
fd1a47c
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
2 times, most recently
from
July 17, 2026 11:57
20d7d41 to
6b76fe7
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
July 21, 2026 01:49
6b76fe7 to
55027c2
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
July 30, 2026 14:13
55027c2 to
62cf356
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
August 12, 2026 00:50
62cf356 to
70cd79c
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
August 26, 2026 12:52
70cd79c to
6da5b0e
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
September 7, 2026 22:04
6da5b0e to
c9f67f8
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
October 1, 2026 04:51
c9f67f8 to
17a8832
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
October 23, 2026 04:27
17a8832 to
b5db0c3
Compare
renovate
Bot
force-pushed
the
renovate/npm-happy-dom-vulnerability
branch
from
October 29, 2026 06:14
b5db0c3 to
ba04190
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This PR body was truncated due to platform limits.
This PR contains the following updates:
^20.0.0→^21.0.0Happy DOM ECMAScriptModuleCompiler: unsanitized export names are interpolated as executable code
CVE-2026-33943 / GHSA-6q6h-j7hj-3r64
More information
Details
Summary
A code injection vulnerability in
ECMAScriptModuleCompilerallows an attacker to achieve Remote Code Execution (RCE) by injecting arbitrary JavaScript expressions insideexport { }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.Details
Vulnerable file:
packages/happy-dom/src/module/ECMAScriptModuleCompiler.ts, lines 371-385The "Export object" handler extracts content from
export { ... }using the regexexport\s*{([^}]+)}, then generates executable code by directly interpolating it:The issue has three root causes:
STATEMENT_REGEXPuses{[^}]+}which matches any content inside braces, not just valid JavaScript identifiersimportNameis placed in code context (as a JS expression to evaluate), not in string context.replace(/["']/g, '')strips"and'but not backticks, so template literal strings like`child_process`survive the filterAttack flow:
Note: This is a different vulnerability from CVE-2024-51757 (SyncFetchScriptBuilder injection) and CVE-2025-61927 (VM context escape). Those were patched in v15.10.2 and v20.0.0 respectively, but this vulnerable code path in
ECMAScriptModuleCompilerremains present in v20.8.4 (latest). In v20.0.0+ where JavaScript evaluation is disabled by default, this vulnerability is exploitable when JavaScript evaluation is explicitly enabled by the user.PoC
Standalone PoC script — reproduces the vulnerability without installing happy-dom by replicating the compiler's exact code generation logic:
Execution result:
HTML attack vector — when processed by happy-dom with JavaScript evaluation enabled:
Impact
An attacker who can inject or control HTML content processed by happy-dom (with JavaScript evaluation enabled) can achieve arbitrary command execution on the host system.
Realistic attack scenarios:
Suggested fix: Validate that
importNameis a valid JavaScript identifier before interpolating it into generated code:Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Happy DOM's fetch credentials include uses page-origin cookies instead of target-origin cookies
CVE-2026-34226 / GHSA-w4gp-fjgq-3q4g
More information
Details
Summary
happy-dommay attach cookies from the current page origin (window.location) instead of the request target URL whenfetch(..., { credentials: "include" })is used. This can leak cookies from origin A to destination B.Details
In
packages/happy-dom/src/fetch/utilities/FetchRequestHeaderUtility.ts(getRequestHeaders()), cookie selection is performed withoriginURL:Here,
originURLrepresents the page URL, not the request destination URL. For outgoing requests, cookie lookup should use the request URL (for example:new URL(options.request[PropertySymbol.url])).PoC Script Content
Environment:
happy-dom20.6.1*.127.0.0.1.nip.ioReproduction steps:
page_cookie=PAGE_ONLYona.127.0.0.1.nip.ioapi_cookie=API_ONLYonb.127.0.0.1.nip.iocredentials: "include"Cookieheader received by the target hostExpected:
api_cookie=API_ONLYpage_cookie=PAGE_ONLYActual (observed):
page_cookie=PAGE_ONLYapi_cookie=API_ONLYObserved output:
Impact
Cross-origin sensitive information disclosure (cookie leakage).
Impacted users are applications relying on
happy-dombrowser-like fetch behavior in authenticated/session-based flows (for example SSR/test/proxy-like scenarios), where cookies from one origin can be sent to another origin.Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Happy DOM: Incomplete fix for CVE-2026-33943: unsanitized import alias leads to host code execution
CVE-2026-115895 / GHSA-834v-8h66-3h79
More information
Details
Summary
The ESM compiler in
happy-dom@20.14.5does not validate imported local binding aliases before interpolating them into generated JavaScript.As a result, an invalid ESM import alias can be transformed into a valid JavaScript destructuring default initializer and executed.
This appears to be an alternate injection path and incomplete remediation of GHSA-6q6h-j7hj-3r64 / CVE-2026-33943. The previous fix validates
importNamein the localexport { ... }handler, but the named import handler still places an unvalidatedaliasdirectly into code context.These issues were confirmed through the public
Windowand<script type="module">APIs using the publishedhappy-domnpm package. The PoC reaches the Node.js hostprocess, obtainsnode:fs, and creates a proof directory on the host filesystem.Confirmed affected versions
The PoC was directly tested against:
happy-dom@17.0.0happy-dom@20.0.0happy-dom@20.1.0happy-dom@20.14.5The same PoC does not trigger on
happy-dom@16.8.1.The ESM compiler was introduced by commit
7bc831df2, first released inv17.0.0. The vulnerable interpolation remains present throughv20.14.5, the latest release at the time of testing.Suggested affected range:
No patched version is currently available.
Preconditions
enableJavaScriptEvaluation: true.Technical details
In
packages/happy-dom/src/module/ECMAScriptModuleCompiler.ts, the named import handler splits an import specifier and extracts its alias:Unlike the patched
export { ... }handler, the value ofaliasis not validated as a JavaScript identifier.It is subsequently inserted directly into generated binding syntax:
Consider the following source:
This is invalid ECMAScript module syntax. Node.js rejects it at the
=token.Happy DOM instead transforms it into the equivalent of:
This generated JavaScript is valid. Because the imported JSON object does not contain a
missingproperty, the default initializer executes.The
with { type: 'json' }attribute is relevant because the compiler only generates its circular import resolver for ESM imports:Using a JSON module prevents the malicious alias from being emitted again in a later circular-import assignment, leaving the generated function syntactically valid.
Backtick strings also survive the existing quote removal. This allows the injected initializer to reach Node.js host APIs:
Proof of concept
The following PoC uses only the public Happy DOM API and performs a harmless filesystem action by creating a directory named
HAPPY_DOM_RCE_PROOF.1. Create
package.json{ "name": "happy-dom-import-alias-rce-poc", "private": true, "type": "module", "dependencies": { "happy-dom": "20.14.5" } }2. Create
dep.json{}3. Create
payload.mjsThis file is used as a control to demonstrate that a native ECMAScript parser rejects the source:
4. Create
poc.mjs5. Run the control test
Expected result:
This confirms that the source is not valid ESM.
6. Run the Happy DOM PoC
node poc.mjsExpected result:
The existence of
HAPPY_DOM_RCE_PROOFconfirms that the expression injected through the import alias executed and reached the host filesystem.The PoC was also verified inside a
node:24-alpineDocker container, where it created:Impact
An attacker who can supply module source to an application that evaluates JavaScript through Happy DOM can cause syntactically invalid import declarations to be transformed into executable JavaScript.
This may bypass upstream syntax validation or application assumptions that malformed import clauses will be rejected.
The demonstrated payload reaches Node.js
processand built-in modules. It can therefore be adapted to read or modify files, access environment data, or execute operating-system commands with the privileges of the Happy DOM host process.Relationship to CVE-2026-33943
CVE-2026-33943 covers expression injection through a local export declaration:
Its fix added identifier validation to the
importNameused by theexport { ... }handler:This report uses a different parsing and code-generation path:
The unvalidated value is the local import
alias, and the injection occurs in a generated destructuring binding rather than the export assignment patched by CVE-2026-33943.The issue remains reproducible in versions released after the CVE-2026-33943 fix, including
20.14.5.Suggested fix
Validate the imported local binding before placing it into code context. The existing
VALID_VARIABLE_NAME_REGEXPcan be reused:A regression test should compile and execute the malicious import declaration, then verify that the initializer was not evaluated.
This change was tested locally. The focused
ECMAScriptModuleCompilertest suite passes with 30 tests, and ESLint reports no errors.For additional hardening, generated property keys should use
JSON.stringify()instead of manual quote interpolation.Verification record
24.14.1happy-dom@20.14.5v20.14.50d4cdbe7442af49d16b49ddf1acf7cc9684ed31817.0.016.8.1Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
capricorn86/happy-dom (happy-dom)
v21.0.4Compare Source
👷♂️ Patch fixes
data:iframes cannot access their parent or top window - By @capricorn86v21.0.3Compare Source
👷♂️ Patch fixes
v21.0.2Compare Source
👷♂️ Patch fixes
v21.0.1Compare Source
👷♂️ Patch fixes
--cssand--iframefor enabling CSS and iframe loading to @happy-dom/server-renderer - By @capricorn86v21.0.0Compare Source
💣 Breaking Changes
<iframe>or<link rel="stylesheet">elements in untrusted HTML to make Happy DOM send HTTP requests from the server to attacker-chosen URLs, including internal services. This could allow access to otherwise unreachable endpoints or trigger unintended actions, depending on the application and its network access.disableCSSFileLoadinghas been deprecated<=v20.14.6by sending in{ enableCSSFileLoading: true, enableIframePageLoading: true }as broswer settings (e.g.new Window({ settings }));v20.14.6Compare Source
👷♂️ Patch fixes
v20.14.5Compare Source
👷♂️ Patch fixes
v20.14.4Compare Source
👷♂️ Patch fixes
v20.14.3Compare Source
👷♂️ Patch fixes
v20.14.2Compare Source
👷♂️ Patch fixes
getComputedStyle()- By @klaesra in task #2344v20.14.1Compare Source
👷♂️ Patch fixes
v20.14.0Compare Source
🎨 Features
v20.13.2Compare Source
👷♂️ Patch fixes
v20.13.1Compare Source
👷♂️ Patch fixes
v20.13.0Compare Source
🎨 Features
v20.12.2Compare Source
👷♂️ Patch fixes
v20.12.1Compare Source
🎨 Features
CSSStyleDeclaration- By @capricorn86 in task #2256CSSStyleDeclaration- By @capricorn86 in task #2256👷♂️ Patch fixes
v20.12.0Compare Source
🎨 Features
Animation,AnimationTimeline,DocumentTimelineandKeyframeEffect- By @capricorn86Element.animate()- By @capricorn86v20.11.15Compare Source
👷♂️ Patch fixes
v20.11.14Compare Source
👷♂️ Patch fixes
v20.11.13Compare Source
👷♂️ Patch fixes
v20.11.12Compare Source
👷♂️ Patch fixes
v20.11.11Compare Source
👷♂️ Patch fixes
v20.11.10Compare Source
👷♂️ Patch fixes
v20.11.9Compare Source
👷♂️ Patch fixes
v20.11.8Compare Source
👷♂️ Patch fixes
adoptedStyleSheetarray should be validated - By @capricorn86 in task #2315v20.11.7Compare Source
👷♂️ Patch fixes
Document.adoptedStyleSheetsandShadowRoot.adoptedStyleSheetsshould validate it's value - By @capricorn86 in task #2313v20.11.6Compare Source
👷♂️ Patch fixes
v20.11.5Compare Source
👷♂️ Patch fixes
querySelector<HTMLInputElement>(".my-input")) - By @cyphercodesv20.11.4Compare Source
👷♂️ Patch fixes
fetch()to match origins instead of host and protocol - By @rexxars in task #1490v20.11.3Compare Source
👷♂️ Patch fixes
v20.11.2Compare Source
👷♂️ Patch fixes
v20.11.1Compare Source
👷♂️ Patch fixes
v20.11.0Compare Source
🎨 Features
v20.10.6Compare Source
👷♂️ Patch fixes
v20.10.5Compare Source
👷♂️ Patch fixes
v20.10.4Compare Source
👷♂️ Patch fixes
v20.10.3Compare Source
👷♂️ Patch fixes
v20.10.2Compare Source
👷♂️ Patch fixes
v20.10.1Compare Source
v20.10.0Compare Source
🎨 Features
v20.9.0Compare Source
🎨 Features
Window.onkeydown) - By @capricorn86 in task #2131v20.8.9Compare Source
👷♂️ Patch fixes
v20.8.8Compare Source
👷♂️ Patch fixes
v20.8.7Compare Source
👷♂️ Patch fixes
Consolewith commonIConsoleinterface to support latest version of Bun - By @YevheniiKotyrlo in task #1845v20.8.6Compare Source
👷♂️ Patch fixes
Request.formData()should honor "Content-Type" header - By @brianhelba in task #2106v20.8.5Compare Source
👷♂️ Patch fixes
connectedCallback()- By @capricorn86 in task #2110v20.8.4Compare Source
👷♂️ Patch fixes
v20.8.3Compare Source
👷♂️ Patch fixes
EventinEventTarget.dispatchEvent()- By @capricorn86 in task #2054v20.8.2Compare Source
👷♂️ Patch fixes
Event.cancelBubbleandEvent.defaultPreventedwhen callingEvent.initEvent()- By @capricorn86 in task #2090v20.8.1Compare Source
👷♂️ Patch fixes
v20.8.0Compare Source
🎨 Features
v20.7.2Compare Source
👷♂️ Patch fixes
v20.7.1Compare Source
👷♂️ Patch fixes
>) and universal (*) query selectors - By @Cherry in task #2078v20.7.0Compare Source
🎨 Features
Window.getScreenDetails()- By @TrevorBurnham in task #1923ScreenfromEventTarget- By @TrevorBurnham in task #1923v20.6.5Compare Source
👷♂️ Patch fixes
[
v20.6.4](https://redirect.github.com/capricorn86/hConfiguration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.