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

