Flagged by CodeRabbit review on PR #675 (the logic is carried over verbatim from the original backend/Generator/main.py, so this predates the refactor).
Problem
backend/Generator/utilities.py -> FileProcessor.process_file() saves the uploaded file using file.filename directly:
file_path = os.path.join(self.upload_folder, file.filename)
file.save(file_path)
A crafted filename such as ../../app.py (or absolute paths / null bytes depending on the WSGI layer) escapes uploads/. Werkzeug's FileStorage.save does sanitize some cases, but relying on framework-level protection is fragile, and os.path.join itself will happily escape when given an absolute path.
Suggested fix
Keep the extension, discard the client-controlled path components:
import uuid
def process_file(self, file):
ext = os.path.splitext(file.filename)[1].lower()
safe_name = f"{uuid.uuid4().hex}{ext}"
file_path = os.path.join(self.upload_folder, safe_name)
...
(Or os.path.basename(file.filename) at minimum, plus an allowlist of .txt/.pdf/.docx.)
Extra notes
- The subsequent
.endswith('.txt'/'.pdf'/'.docx') dispatch already implies an allowlist; enforcing it before saving closes the hole fully.
- Happy to submit this as a PR once triaged.
Flagged by CodeRabbit review on PR #675 (the logic is carried over verbatim from the original
backend/Generator/main.py, so this predates the refactor).Problem
backend/Generator/utilities.py->FileProcessor.process_file()saves the uploaded file usingfile.filenamedirectly:A crafted filename such as
../../app.py(or absolute paths / null bytes depending on the WSGI layer) escapesuploads/. Werkzeug'sFileStorage.savedoes sanitize some cases, but relying on framework-level protection is fragile, andos.path.joinitself will happily escape when given an absolute path.Suggested fix
Keep the extension, discard the client-controlled path components:
(Or
os.path.basename(file.filename)at minimum, plus an allowlist of.txt/.pdf/.docx.)Extra notes
.endswith('.txt'/'.pdf'/'.docx')dispatch already implies an allowlist; enforcing it before saving closes the hole fully.