### Description
While reviewing the recently updated `/api/ai` endpoints, I noticed an unpatched edge case in the caching mechanism that allows for an Event Loop Blocking Denial of Service (DoS) attack.
In `server/routes/ai.js`, the incoming request is validated to ensure specific keys (like `code`, `language`, `error`) are strings. However, this validation loop uses `Object.entries(stringFields)` and completely ignores any *additional* or *unexpected* properties injected into the `req.body` by an attacker.
Later in the file (Line ~102), the caching middleware generates a cache key by synchronously stringifying the entire request body:
```javascript
const bodyHash = crypto.createHash('sha256').update(JSON.stringify(req.body)).digest('hex');
Security Impact
Since the Express global body limit is set to 1MB, an attacker can send a request containing a deeply nested, highly complex 1MB JSON object attached to an arbitrary property (e.g., {"code": "print()", "malicious_payload": { ... 1MB nested object ... }}).
Because JSON.stringify() runs synchronously, stringifying a complex 1MB object will block the Node.js event loop for a significant amount of time. An attacker spamming this endpoint will easily hang the server, causing a DoS for all legitimate users.
Suggested Fix
Instead of stringifying the entire req.body, we should construct a sanitized object that only contains the explicitly allowed properties, and stringify that sanitized object instead.
Example fix:
// Build a stable hash from ONLY the validated fields, ignoring malicious extras
const sanitizedBody = {
code: req.body.code,
error: req.body.error,
language: req.body.language,
question: req.body.question,
previousExplanation: req.body.previousExplanation,
input: req.body.input
};
const bodyHash = crypto.createHash('sha256').update(JSON.stringify(sanitizedBody)).digest('hex');
I would love to be assigned this issue so I can submit a PR with the fix. /assign under GSSoC!
Security Impact
Since the Express global body limit is set to 1MB, an attacker can send a request containing a deeply nested, highly complex 1MB JSON object attached to an arbitrary property (e.g.,
{"code": "print()", "malicious_payload": { ... 1MB nested object ... }}).Because
JSON.stringify()runs synchronously, stringifying a complex 1MB object will block the Node.js event loop for a significant amount of time. An attacker spamming this endpoint will easily hang the server, causing a DoS for all legitimate users.Suggested Fix
Instead of stringifying the entire
req.body, we should construct a sanitized object that only contains the explicitly allowed properties, and stringify that sanitized object instead.Example fix:
I would love to be assigned this issue so I can submit a PR with the fix. /assign under GSSoC!