Nodejs ws, Uninitialized Memory Disclosure, CVE-2024-37890 (medium)

Listen to this Post

The vulnerability exists in the `WebSocket.close()` method when a `TypedArray` (e.g., Float32Array, Uint8Array) is passed as the `reason` argument instead of a standard string or Buffer. Internally, `ws` copies the `reason` data into a buffer for transmission. However, if the `TypedArray` is not fully initialized (e.g., its underlying memory contains stale, uninitialized bytes), the `ws` implementation fails to properly validate or sanitize the length. Instead of using the TypedArray‘s actual byte length, it may read from the underlying `ArrayBuffer` up to a larger bound, including uninitialized heap memory. This occurs because `TypedArray` objects can be created with `new Float32Array(20)` which allocates a new buffer but does not zero-fill it (depending on engine optimizations). When `ws.close(1000, typedArray)` is called, the library attempts to serialize the `TypedArray` as a Buffer. The flawed logic in versions prior to 8.20.1 does not correctly clamp the read to the TypedArray‘s length, leading to out-of-bounds read of up to 80 bytes of uninitialized memory. An attacker who can control the `TypedArray` contents (or lack thereof) could potentially leak sensitive data from the Node.js heap, such as other WebSocket messages, session tokens, or cryptographic keys. The proof of concept shows a server closing with `new Float32Array(20)` (80 bytes) and the client receiving a `reason` buffer of exactly 80 zeros (after fix) but before fix, uninitialized bytes appear. The fix in `[email protected]` ensures proper length checks and zero-initializes the copied buffer.
Platform: Node.js ws
Version: <8.20.1
Vulnerability : Uninitialized memory disclosure
Severity: Medium
date: 2024-08-30

Prediction: Patch available 2024-08-27

What Undercode Say:

Check ws version
npm list ws
Update to patched version
npm install [email protected]
Verify fix with proof of concept
node -e "const {WebSocket,WebSocketServer}=require('ws');new WebSocketServer({port:0},function(){const ws=new WebSocket('ws://localhost:'+this.address().port);ws.on('close',(c,r)=>console.log(r.length));});wss.on('connection',ws=>ws.close(1000,new Float32Array(20)));"

Exploit:

Attacker runs Node.js script that connects to a vulnerable ws server. The server calls `ws.close(1000, new Float32Array(20))` (or any uninitialized TypedArray). The client receives a `reason` buffer containing up to 80 bytes of leaked heap memory, including data from previous allocations.

Protection from this CVE

Upgrade to [email protected] or later. If unable, avoid passing TypedArray to close(). Always use `Buffer` or `string` for reason. Implement input validation to ensure `reason` length matches expected bounds.

Impact:

Leak of uninitialized memory (up to 80 bytes) per malicious close frame. Can expose secrets, cross-message data, or process memory. Low likelihood in practice but moderate CVSS score due to confidentiality impact.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top