PERF/SECURITY: make uploads streaming/bounded instead of allowing multi-GB blocking and in-memory expansion #41
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
nsaspy/a0-symbolics#41
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Finding
The UI server defaults both
MAX_CONTENT_LENGTHandMAX_FORM_MEMORY_SIZEto 5 GiB. The upload paths do not consistently impose a smaller effective file limit or keep large file work off the async request path.Concrete paths:
api/upload.pyaccepts every extension (allowed_file()immediately returnsTrue) and callsFileStorage.save()synchronously from an async handler.api/upload_work_dir_files.pyproduction mode calls synchronousFileBrowser.save_files()from an async handler.file.stream.read()for the complete upload, base64-encodes the whole byte string (adding ~33% size overhead plus copies), then transports that string through the development-function bridge.FileBrowser.MAX_FILE_SIZE = 100 MiBand_check_file_size()exist, but_is_allowed_file()simply returnsTrueand never invokes the size check, so that apparent safety limit is not enforced bysave_files().A large authenticated upload can therefore monopolize memory/event-loop time, and development mode can expand a large request into multiple simultaneous full-size buffers.
Direction
Define one upload policy and enforce it before/while streaming:
read()+ base64 whole-file expansionAcceptance
FileBrowser.MAX_FILE_SIZEis either actually enforced or removed/replaced by the authoritative limit; there is no decorative dead limit.