fix(ask-ai): reject oversized payloads before parsing to prevent memory exhaustion#502
fix(ask-ai): reject oversized payloads before parsing to prevent memory exhaustion#502anshul23102 wants to merge 1 commit into
Conversation
…ry exhaustion The imageBase64 field is loaded fully into server memory by req.json() before the slice(0, 500) truncation. A request with a multi-megabyte body allocates that full payload on the heap on every call. Adds a Content-Length guard before req.json() that returns 413 immediately for payloads above 512 KB, keeping memory usage predictable under load. Fixes knoxiboy#470
|
CodeAnt AI is reviewing your PR. |
|
@anshul23102 is attempting to deploy a commit to the Karan Mani Tripathi 's projects Team on Vercel. A member of the Team first needs to authorize it. |
❌ PR Rejected — Issue Assignment Check FailedHi @anshul23102! This PR has been closed because you are not assigned to the issue(s) it references:
What to do:
|
|
@coderabbitai review |
|
@coderabbitai review |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThis PR adds a defensive request-size check to the ask-ai endpoint. A ChangesRequest Size Validation
🎯 1 (Trivial) | ⏱️ ~3 minutes ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed: dependency version conflict. Check your lock file or package.json. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| const contentLength = parseInt(req.headers.get('content-length') ?? '0', 10); | ||
| if (contentLength > MAX_BODY_BYTES) { |
There was a problem hiding this comment.
Suggestion: This size guard trusts the client-supplied Content-Length header, so a request sent with chunked transfer encoding (no Content-Length) or a missing header bypasses the check and still reaches req.json(), allowing large bodies to be fully buffered in memory. Enforce the limit based on actual bytes read from the request stream (or reject requests without a valid length for this endpoint) so oversized payloads cannot bypass the protection. [security]
Severity Level: Major ⚠️
- ❌ /api/ask-ai accepts >512 KB bodies via chunked.
- ❌ Memory usage spikes when large chunked bodies parsed.
- ⚠️ 512 KB limit ineffective against crafted HTTP clients.Steps of Reproduction ✅
1. Start the DoubtDesk application so the Next.js API route implemented in
`src/app/api/ask-ai/route.ts` is served; this route defines `export async function
POST(req: Request)` with the `contentLength` guard at approximately lines 32–38 (as seen
in the file content).
2. From a custom HTTP client (e.g., `nc`, `telnet`, or a raw Node.js `net` socket), send
an HTTP/1.1 request to `POST /api/ask-ai` with headers including `Transfer-Encoding:
chunked` and **no `Content-Length` header**, and a JSON body larger than 512 KB (for
example, a large `imageBase64` string) so that the request remains under the framework's
global 4 MB limit but above `MAX_BODY_BYTES`.
3. On the server, the POST handler at `src/app/api/ask-ai/route.ts` executes the guard
`const contentLength = parseInt(req.headers.get('content-length') ?? '0', 10);` followed
by `if (contentLength > MAX_BODY_BYTES) { ... }`. Because the request is chunked and omits
`Content-Length`, `req.headers.get('content-length')` returns `null`, `parseInt('0', 10)`
yields `0`, and the `if (contentLength > MAX_BODY_BYTES)` condition at lines 211–212
evaluates to `false`, so the 413 response is not triggered.
4. Execution continues into the rest of the POST handler, which later calls `await
req.json()` to parse the request body; this causes the full >512 KB JSON payload
(including the large `imageBase64` field) to be read and buffered into memory, bypassing
the intended size restriction and allowing repeated large requests to consume significant
heap memory under concurrent load.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/app/api/ask-ai/route.ts
**Line:** 211:212
**Comment:**
*Security: This size guard trusts the client-supplied `Content-Length` header, so a request sent with chunked transfer encoding (no `Content-Length`) or a missing header bypasses the check and still reaches `req.json()`, allowing large bodies to be fully buffered in memory. Enforce the limit based on actual bytes read from the request stream (or reject requests without a valid length for this endpoint) so oversized payloads cannot bypass the protection.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| const MAX_BODY_BYTES = 512 * 1024; // 512 KB | ||
|
|
||
| export async function POST(req: Request) { | ||
| try { | ||
| // Reject oversized payloads before parsing JSON to avoid loading | ||
| // a multi-megabyte body into memory only to discard most of it. | ||
| const contentLength = parseInt(req.headers.get('content-length') ?? '0', 10); | ||
| if (contentLength > MAX_BODY_BYTES) { | ||
| return NextResponse.json( | ||
| { error: 'Request payload too large. Maximum size is 512 KB.' }, | ||
| { status: 413 } |
There was a problem hiding this comment.
🟠 Architect Review — HIGH
The new 512 KB server-side body limit for /api/ask-ai reduces the maximum accepted image payload well below what the Ask AI UI promises ("Max 10MB") and below what the client currently enforces, so typical camera-sized uploads that previously worked will now be rejected with 413 while the UI still suggests larger files are acceptable.
Suggestion: Align the backend limit with the product flow by either increasing the server limit or, if 512 KB is required, adding client-side file-size enforcement/compression plus updated UX copy and explicit handling of 413 responses in src/app/ask-ai/page.tsx so users are warned before upload and see a clear size-related error.
Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is an **Architect / Logical Review** comment left during a code review. These reviews are first-class, important findings — not optional suggestions. Do NOT dismiss this as a 'big architectural change' just because the title says architect review; most of these can be resolved with a small, localized fix once the intent is understood.
**Path:** src/app/api/ask-ai/route.ts
**Line:** 205:215
**Comment:**
*HIGH: The new 512 KB server-side body limit for /api/ask-ai reduces the maximum accepted image payload well below what the Ask AI UI promises ("Max 10MB") and below what the client currently enforces, so typical camera-sized uploads that previously worked will now be rejected with 413 while the UI still suggests larger files are acceptable.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
If a suggested approach is provided above, use it as the authoritative instruction. If no explicit code suggestion is given, you MUST still draft and apply your own minimal, localized fix — do not punt back with 'no suggestion provided, review manually'. Keep the change as small as possible: add a guard clause, gate on a loading state, reorder an await, wrap in a conditional, etc. Do not refactor surrounding code or expand scope beyond the finding.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix|
CodeAnt AI finished reviewing your PR. |
User description
Problem Statement
src/app/api/ask-ai/route.tscallsawait req.json()without any prior body size check. TheimageBase64field is read entirely into server memory before theimageBase64?.slice(0, 500)truncation at line 516. A single request carrying a multi-megabyte base64 string allocates the full payload on the server heap before any truncation occurs. Under concurrent load, this is a viable path to memory exhaustion.Current behavior: Any authenticated user can send a request up to the Next.js default body limit (4 MB) and the server will allocate it fully in memory before discarding most of it.
Expected behavior: Oversized requests are rejected before JSON parsing begins.
Root Cause Analysis
The
POSThandler inroute.tsreads the request body unconditionally:The
imageBase64value is only truncated after allocation:There is no Content-Length guard before this parse, so any body up to the framework default limit passes through.
Solution Overview
Add a
Content-Lengthheader check at the top of thePOSThandler, beforereq.json()is called. Requests exceeding 512 KB receive a413 Payload Too Largeresponse immediately, with zero body parsing overhead.512 KB is generous for all legitimate prompt and history payloads while blocking the multi-megabyte base64 inputs that cause the issue.
Changes Made
src/app/api/ask-ai/route.ts
MAX_BODY_BYTESconstant (512 KB) above thePOSTexport.Content-Lengthcheck as the first operation inside thePOSThandler, before any database access or JSON parsing.413with a clear error message when the limit is exceeded.Type of Change
Testing Done
Manual Testing Steps
Test Case 1: Normal request
POST /api/ask-aiwith a prompt under 512 KB.Expected: Request proceeds normally, response returned.
Actual: Passes the guard and reaches existing logic.
Test Case 2: Oversized request
POST /api/ask-aiwith a body larger than 512 KB (e.g. a large base64 string).Expected:
413 Payload Too Largereturned immediately.Actual: Guard fires before
req.json()is called.Edge Cases Tested
parseInt(null ?? '0', 10)evaluates to0, so the guard does not reject it (the body itself is still bounded by the framework limit).Screenshots or Demo
Not applicable. Server-side JSON parsing guard with no visual component.
Related Issue
Closes #470
Checklist
GSSoC Label Request
Maintainer, could you please add the appropriate GSSoC label to this PR? This helps with contribution tracking and scoring under GSSoC '26. Thank you!
Summary by CodeRabbit
CodeAnt-AI Description
Reject oversized ask-ai requests before reading the body
What Changed
Impact
✅ Fewer memory exhaustion crashes✅ Lower risk of slow ask-ai requests under load✅ Clearer oversized request errors💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.