Overview
Unrestricted Resource Consumption vulnerabilities occur when an application processes unbounded input or performs unbounded work in response to a single request, allowing an attacker to exhaust memory, CPU, or file descriptors. The historic CVE-1999-0967 describes a buffer overflow in the HTML library used by Internet Explorer, Outlook Express, and Windows Explorer via the res: local resource protocol, illustrating how unsafe handling of resource data can crash a component. While that CVE predates Node.js, it demonstrates how untrusted inputs to resource-handling code can lead to critical failures when there is no bound on what the code will load or process.\n\nIn Node.js with Express, the same class of attack manifests when endpoints accept large payloads (JSON bodies, file uploads, or computational tasks) without enforcing size limits or backpressure. Because Node.js runs on a single event loop, feeding it oversized requests or by performing heavy CPU-bound work in the request path can exhaust memory or stall the event loop, causing service slowdown or outages. This is the practical version of unrestricted resource consumption in modern web servers.\n\nTo mitigate, implement strict input bounds and offload heavy work. The code examples below show how to reuse request-parsing limits, validate and cap inputs, and move heavy processing out of the request path. Tying the defense to CVE-1999-0967 emphasizes that improper resource handling remains a core DoS risk even as architectures evolve.
Code Fix Example
Node.js (Express) API Security Remediation
/* Vulnerable and Fixed example in one file (Express) */
const express = require('express');
const app = express();
// Vulnerable: no body size limit and in-memory processing of large payloads
app.use(express.json());
app.post('/vulnerable/process', (req, res) => {
const nums = req.body.nums;
if (!Array.isArray(nums)) return res.status(400).send('invalid');
let sum = 0;
for (let i = 0; i < nums.length; i++) {
sum += Number(nums[i]);
}
res.json({ sum, count: nums.length });
});
// Fixed: enforce payload limit and cap processing
app.use(express.json({ limit: '100kb' }));
app.post('/fixed/process', (req, res) => {
const nums = req.body.nums;
if (!Array.isArray(nums)) return res.status(400).send('invalid');
const maxItems = 1000;
const limited = nums.slice(0, maxItems);
let sum = 0;
for (let i = 0; i < limited.length; i++) sum += Number(limited[i]);
res.json({ sum, count: limited.length });
});
app.listen(process.env.PORT || 3000, () => console.log('Server started'));