Skip to content

fix(Generator): save uploads under a server-generated filename - #677

Open
harshita-singh12 wants to merge 4 commits into
AOSSIE-Org:mainfrom
harshita-singh12:fix-upload-path-hardening
Open

fix(Generator): save uploads under a server-generated filename#677
harshita-singh12 wants to merge 4 commits into
AOSSIE-Org:mainfrom
harshita-singh12:fix-upload-path-hardening

Conversation

@harshita-singh12

@harshita-singh12 harshita-singh12 commented Aug 27, 2026

Copy link
Copy Markdown

Fixes #676

Problem

FileProcessor.process_file() built the on-disk path by joining the client-controlled file.filename with the upload folder. A crafted filename such as ../../app.py escapes uploads/, so file.save() can overwrite any process-writable file and the subsequent os.remove() can delete it.

Fix

  • The storage filename is now generated server-side (uuid.uuid4().hex), so the on-disk path can never escape the upload folder regardless of what the client sends.
  • Only the extension is preserved from the client name, and only when it is one of the three types the extraction dispatch actually handles (.txt, .pdf, .docx). Anything else returns "" before anything is written to disk, which matches the previous outcome for unsupported types (/upload responds 400).
  • Extension-based dispatch now keys off the validated extension instead of re-reading file.filename.

Testing

Validated the process_file logic directly (module import stubbed for heavy ML deps):

  • normal .txt upload round-trips and the saved path is inside the upload folder with a uuid name;
  • filenames ../../evil.txt and ../server.docx are saved inside the upload folder (no file created outside it);
  • unsupported extension (.md) saves nothing and returns "" (same /upload 400 response as before).

Summary by CodeRabbit

  • Bug Fixes
    • Improved file upload handling with unique server-generated filenames.
    • Restricted uploads to supported TXT, PDF, and DOCX formats.
    • Improved text extraction by consistently recognizing validated file types.
    • Unsupported file formats are now rejected consistently, helping prevent upload and processing issues.

The upload path was built by joining the client-supplied filename with
the upload folder, so a crafted name like ../../app.py could escape
uploads/ and let file.save() overwrite arbitrary process-writable files
(and os.remove() delete them afterwards).

Derive the on-disk name from uuid4() on the server and keep only the
extension, which already drives the text-extraction dispatch. File
extensions outside the supported .txt/.pdf/.docx set are rejected before
anything touches the disk, matching the previous behavior of returning
empty content for unsupported types.
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8f755d1d-5e04-44c3-b9b8-a17ee1a1556d

📥 Commits

Reviewing files that changed from the base of the PR and between e766319 and 9c68fcd.

📒 Files selected for processing (1)
  • backend/Generator/main.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/Generator/main.py

Included review availability: Your plan provides up to 2 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

FileProcessor.process_file now accepts only .txt, .pdf, and .docx files. It saves accepted files with server-generated UUID filenames and uses the validated extension for extraction. Extraction methods now include documentation.

Changes

Secure upload processing

Layer / File(s) Summary
Validated UUID upload handling
backend/Generator/main.py
FileProcessor.process_file rejects unsupported extensions, saves accepted files with UUID-based names, preserves the extension, and selects extraction logic from the validated extension. PDF and DOCX extraction methods now include docstrings.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 9c68f

The change stores uploads under server-generated filenames and validates supported extensions before writing files; no actionable merge-blocking risk remains beyond normal checks and review.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 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: uploads now use server-generated filenames.
Linked Issues check ✅ Passed The changes satisfy issue #676. They prevent client-controlled upload paths, preserve only supported extensions, reject unsupported extensions before saving, and dispatch extraction using the validate…
Out of Scope Changes check ✅ Passed The changes remain within scope. They address upload filename safety, extension validation, and extraction dispatch required by issue #676.
Full details: Linked Issues check

Explanation

The changes satisfy issue #676. They prevent client-controlled upload paths, preserve only supported extensions, reject unsupported extensions before saving, and dispatch extraction using the validated extension.

  • Fix all pre-merge checks with AI

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.

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.

Security: FileProcessor.process_file uses client-controlled filename as on-disk path

1 participant