T09 · Insecure Skill Coding Practices
- Location
api-server/server.js:36- Finding
Unbounded HTTP Request Body Enables Remote Denial of Service
- Content
View full analysis
Vulnerability Details
File Location:
api-server/server.js:36-50
Vulnerability Type: Uncontrolled resource consumption through unbounded request buffering
Risk Level: Medium
Classification: T09: Insecure Skill Coding PracticesVulnerable Code
js // Parse JSON body async function parseBody(req) { return new Promise((resolve, reject) => { let body = ''; req.on('data', chunk => body += chunk); req.on('end', () => { try { resolve(body ? JSON.parse(body) : {}); } catch (e) { reject(new Error('Invalid JSON')); } }); req.on('error', reject); }); }The unbounded parser is invoked for every POST request at
api-server/server.js:95-96:js // POST endpoints if (req.method === 'POST') { const body = await parseBody(req);Technical Analysis
parseBody()appends every incoming chunk to an in-memory string without enforcing a maximum body size. It also does not implement a request timeout or abort processing when a client sends data too slowly.An attacker who can reach the HTTP server can therefore submit an arbitrarily large JSON request. The server retains the request content in memory, creates additional allocations while concatenating strings, and then passes the body to
JSON.parse(). For valid requests, the supplied text is subsequently processed by synchronous pattern-matching and statistical-analysis routines, increasing CPU and memory pressure.The server starts with
server.listen(PORT)and does not explicitly restrict itself to a loopback address. Exposure depends on the runtime environment and network controls, but the code itself does not enforce local-only access. No authentication or rate limiting mitigates repeated requests.Attack Path
- The attacker obtains network access to the configured API port.
- The attacker opens one or more POST requests to an API endpoint such as
/api/analyze. - The attacker streams an oversized JSON body o ...[truncated 905 chars]
- Remediation
View remediation
Remediation Suggestions
- Enforce a strict request-body limit. Track received bytes rather than JavaScript string length. Reject oversized requests with HTTP
413 Payload Too Largeand destroy the request stream.
js const MAX_BODY_BYTES = 1_000_000; async function parseBody(req) { return new Promise((resolve, reject) => { const chunks = []; let received = 0; let settled = false; req.on('data', (chunk) => { received += chunk.length; if (received > MAX_BODY_BYTES) { settled = true; const error = new Error('Request body too large'); error.statusCode = 413; req.destroy(error); reject(error); return; } chunks.push(chunk); }); req.on('end', () => { if (settled) return; try { const body = Buffer.concat(chunks).toString('utf8'); resolve(body ? JSON.parse(body) : {}); } catch { const error = new Error('Invalid JSON'); error.statusCode = 400; reject(error); } }); req.on('error', (error) => { if (!settled) reject(error); }); }); }-
Return appropriate status codes. Map oversized bodies to HTTP 413 and malformed JSON to HTTP 400 rather than exposing all parser failures as HTTP 500.
-
Validate the parsed input. Require
body.textto be a string and enforce a separate maximum text length before invoking analysis routines. -
Configure timeouts. Set
server.requestTimeout,server.headersTimeout, andserver.keepAliveTimeoutto bounded values to reduce slow-request attacks. -
Restrict default network exposure. Bind to
127.0.0.1by default and require explicit configuration to listen on external interfaces:
js const HOST = process.env.HOST || '127.0.0.1'; server.listen(PORT, HOST);- Protect public deployments. Place the server behind a reverse proxy or gateway that provides authentication, per-client rate limiting, connection limits, a ...[truncated 220 chars]
- Enforce a strict request-body limit. Track received bytes rather than JavaScript string length. Reject oversized requests with HTTP
