Skip to content

Sanitize buffered upload filenames - #6753

Open
harsh21234i wants to merge 4 commits into
reflex-dev:mainfrom
harsh21234i:fix/upload-filename-basename-buffered
Open

Sanitize buffered upload filenames#6753
harsh21234i wants to merge 4 commits into
reflex-dev:mainfrom
harsh21234i:fix/upload-filename-basename-buffered

Conversation

@harsh21234i

Copy link
Copy Markdown
Contributor

Description

close #6752
Buffered uploads previously preserved client-supplied path segments in UploadFile.path, while streamed uploads
normalized filenames to a basename.

This made rx.upload_files and rx.upload_files_chunk expose different filename/path behavior for the same multipart
filename, for example ../secret.txt.

This PR adds one shared filename sanitizer and uses it for both upload paths.

Changes

  • Add _sanitize_upload_filename to strip path segments from upload filenames.
  • Add _upload_file_from_starlette so buffered upload file construction is directly testable.
  • Use the shared sanitizer in both buffered and streamed upload handling.
  • Add tests for POSIX-style and Windows-style path segment filenames.

Checks

  • uv run pytest tests/units/components/core/test_upload.py -q
  • uv run ruff check packages/reflex-components-core/src/reflex_components_core/core/_upload.py tests/units/ components/core/test_upload.py
  • uv run ruff format --check packages/reflex-components-core/src/reflex_components_core/core/_upload.py tests/units/ components/core/test_upload.py
  • uv run pyright packages/reflex-components-core/src/reflex_components_core/core/_upload.py tests/units/components/ core/test_upload.py

@harsh21234i
harsh21234i requested a review from a team as a code owner July 13, 2026 06:53
@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR aligns filename handling for buffered and streamed uploads. The main changes are:

  • Adds a shared sanitizer for client-supplied upload filenames.
  • Preserves safe relative directory paths while removing traversal segments.
  • Uses the sanitizer in both buffered and streamed upload paths.
  • Adds tests for POSIX and Windows path formats.

Confidence Score: 5/5

This looks safe to merge.

  • The shared sanitizer is used by both upload paths.
  • The updated tests cover the intended POSIX, Windows, and relative-directory behavior.
  • No separate blocking issue remains in the reviewed changes.

Important Files Changed

Filename Overview
packages/reflex-components-core/src/reflex_components_core/core/_upload.py Adds the shared filename sanitizer and applies it to buffered and streamed uploads.
tests/units/components/core/test_upload.py Adds coverage for path sanitization and preserved relative directories in both upload modes.
packages/reflex-components-core/news/6753.bugfix.md Documents the aligned filename sanitization behavior.

Reviews (4): Last reviewed commit: "Merge branch 'main' into fix/upload-file..." | Re-trigger Greptile

Comment thread packages/reflex-components-core/src/reflex_components_core/core/_upload.py Outdated
@codspeed-hq

codspeed-hq Bot commented Jul 13, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 3.96%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 25 untouched benchmarks
⏩ 8 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation test_var_access[non_mutable_scalar] 57.5 ms 59.9 ms -3.96%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing harsh21234i:fix/upload-filename-basename-buffered (cd91912) with main (346177c)2

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (d8a132b) during the generation of this report, so 346177c was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@masenf masenf left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it seems like this breaks directory upload.

if you make an upload component, then drag a whole directory onto it and upload it, i would expect the path segments to be retained.

@harsh21234i

Copy link
Copy Markdown
Contributor Author

Good catch. I adjusted the sanitizer so directory uploads keep safe relative paths instead of flattening everything to
a basename.

Current behavior:

  • photos/2026/image.png is preserved for directory uploads.
  • ../secret.txt is normalized to secret.txt.
  • absolute / drive paths still collapse to basename.

I added coverage for both buffered uploads and streamed upload chunks to make sure safe directory paths are retained
consistently.

@harsh21234i

Copy link
Copy Markdown
Contributor Author

hey @masenf can you go through this?

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.

Buffered uploads preserve path segments in UploadFile.path while streamed uploads sanitize to basename

2 participants