Skip to content

fix: enforce 10 MB size limit on avatar uploads#658

Open
neuron-tech-ai wants to merge 2 commits into
jamiepine:mainfrom
neuron-tech-ai:fix/avatar-upload-size-limit
Open

fix: enforce 10 MB size limit on avatar uploads#658
neuron-tech-ai wants to merge 2 commits into
jamiepine:mainfrom
neuron-tech-ai:fix/avatar-upload-size-limit

Conversation

@neuron-tech-ai
Copy link
Copy Markdown

@neuron-tech-ai neuron-tech-ai commented May 14, 2026

The avatar upload endpoint previously had no server-side size check. An oversized image would be fully read into memory before anything rejected it — a trivial vector for memory exhaustion.

This adds an explicit 10 MB limit enforced before the file is read, returning a clear 413 error to the client. Consistent with the upload size guard applied elsewhere in the codebase.

Summary by CodeRabbit

  • Bug Fixes
    • Profile avatar uploads now enforce a maximum file size limit to prevent server resource exhaustion and improve platform stability.
    • Oversized uploads return a clear error response for better user feedback.
    • Enhanced memory efficiency during the upload process.

Review Change Stack

upload_profile_avatar previously read the entire file into memory with
await file.read() and no size check, making it trivial to exhaust server
memory with an oversized upload. Switch to a chunked read loop that
rejects payloads above 10 MB with HTTP 413, consistent with the sample
upload (50 MB) and audio import (200 MB) endpoints that already enforce
their own limits.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

Warning

Rate limit exceeded

@neuron-tech-ai has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 1 minute and 3 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 41abb1d3-73a3-45f0-afc1-c20ddb7432c8

📥 Commits

Reviewing files that changed from the base of the PR and between 62eb825 and 031198a.

📒 Files selected for processing (1)
  • backend/routes/profiles.py
📝 Walkthrough

Walkthrough

The avatar upload handler is refactored to stream chunks of the request body into a temporary file instead of reading the entire upload into memory. Two constants define the 10 MB max file size and 1 MB chunk size. The handler rejects uploads exceeding the limit with HTTP 413, derives the temp filename suffix from the original upload filename (defaulting to .png), and cleans up the temp file after processing.

Changes

Avatar Upload Streaming

Layer / File(s) Summary
Chunked upload with size validation
backend/routes/profiles.py
Constants AVATAR_MAX_FILE_SIZE (10 MB) and AVATAR_UPLOAD_CHUNK_SIZE (1 MB) are added. The upload_profile_avatar handler streams the request body in fixed-size chunks, accumulates byte counts, raises HTTP 413 if the total exceeds the limit, determines the temp file suffix from the upload filename with .png fallback, and ensures cleanup in a finally block.

🎯 2 (Simple) | ⏱️ ~10 minutes

🐰 A rabbit hops with delight,

Streaming chunks, not loading all in sight,

Ten megabytes, the limit's set,

No more memory to regret! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: enforcing a 10 MB size limit on avatar uploads, which matches the primary objective of preventing memory exhaustion and adding server-side size validation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/routes/profiles.py`:
- Line 239: The code currently sets suffix = Path(file.filename or "").suffix or
".png" without validating it; add an allowed image extensions set (e.g.,
ALLOWED_IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".webp"}) and
normalize suffix to lowercase, then check that suffix is in that set before
continuing. If the suffix is missing or not allowed, respond with an error
(raise HTTPException / return 400) instead of defaulting to ".png". Update the
upload handler that references file.filename and the suffix variable to perform
this check and reject disallowed extensions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 431b82ef-3f23-4441-8fc2-b523bb7b271e

📥 Commits

Reviewing files that changed from the base of the PR and between b35b909 and 62eb825.

📒 Files selected for processing (1)
  • backend/routes/profiles.py

Comment thread backend/routes/profiles.py Outdated
Reject uploads with unsupported extensions (e.g. .exe, .php) with a 400
rather than accepting any extension. Only .png, .jpg, .jpeg, .gif, .webp,
.bmp, and .svg are allowed; missing extension defaults to .png.
@neuron-tech-ai
Copy link
Copy Markdown
Author

Addressed the CodeRabbit review comment:

Validate uploaded file extensions: Added an _ALLOWED_IMAGE_EXTS set (.png, .jpg, .jpeg, .gif, .webp, .bmp, .svg). The handler now checks the lowercase extension and raises HTTP 400 if an unsupported extension is uploaded. Missing extensions still default to .png.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant