Treat every file as untrusted

The file extension and browser-provided content type can be forged. Check the file's actual format on the server and allow only the types the feature needs.

Set limits for file size and, where relevant, image dimensions or archive expansion. Reject unsupported files with a clear message before they consume expensive processing time.

Store uploads away from application code

Use a dedicated object store or a non-executable storage path. Generate a random storage key rather than trusting a user-provided filename.

Keep private files behind authorization checks. Use short-lived signed links when a user needs temporary access, and scan files when the product's risk calls for it.

Protect the upload endpoint

Require authentication and permission checks for private uploads. Add request limits, validate metadata, and ensure that users cannot overwrite someone else's file by guessing a path.

Test rejected formats, large files, interrupted uploads, and attempts to retrieve a private file as another user.