Overview
A vulnerability in Node.js has been identified, allowing for a Denial of Service (DoS) attack through resource exhaustion when using the fetch() function to retrieve content from an untrusted URL. The vulnerability stems from the fact that the fetch() function in Node.js always decodes Brotli, making it possible for an attacker to cause resource exhaustion when fetching content from an untrusted URL. An attacker controlling the URL passed into fetch() can exploit this vulnerability to exhaust memory, potentially leading to process termination, depending on the system configuration.
Details
Module Info
- Product: Node.js
- Affected versions: <21.6.2, <20.11.1, <v18.19.1, <= 16.20.2
- GitHub repository: https://github.com/nodejs/node
- Fixed in: Node.js NES v16, v18
Vulnerability Info
The vulnerability arises when Node.js automatically decompresses Brotli data in the fetch() function without properly managing memory usage. When fetch() retrieves content from an untrusted URL, an attacker can send a large or specially crafted Brotli-compressed payload. This can lead to excessive memory consumption, potentially causing Denial of Service (DoS) by overloading system resources, which may result in process termination or instability. The issue stems from Node.js’s lack of buffer management when decompressing large files, allowing for a resource exhaustion attack.
Proof Of Concept
A full reproduction:
'use strict';
const { createBrotliDecompress } = require('node:zlib');
const assert = require('node:assert');
const content = 'A MASSIVE STRING'; // Use a large hex string
const buf = Buffer.from(content, 'hex');
const decoder = createBrotliDecompress();
decoder.end(buf);
// Wait to verify that the libuv thread pool has processed the data
setTimeout(() => {
// Ensure the buffer contains data
assert.strictEqual(decoder._readableState.buffer.length, 1);
}, 100);
Mitigation
The v16 line of the Node.js project is End Of Life and will not receive any updates to address this issue.
Users of the affected components should apply one of the following mitigations:
- Migrate affected applications away to EOL versions.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.