APS-43Required
Check every uploaded file
Accept only the file types you need, check them by content, limit their size, and store them where they cannot run.
How to do it
Read the first bytes to find the type, and don't trust the name or the browser's type. Set a size limit per type, such as 10 MB for images, in the web server and in the app. Give every file a random name. Store it outside the web folder or on a separate domain. Serve it with X-Content-Type-Options: nosniff and Content-Disposition: attachment unless it is a known image. Treat SVG as active content, because it can hold scripts. See also confirm every upload on the server and scan files for malware before anyone opens them.
Examples
HTTP example
HTTP/2 200
content-type: application/octet-stream
content-disposition: attachment; filename="upload.bin"
x-content-type-options: nosniff
How to check
On the test copy, the agent uploads a harmless HTML file renamed to .jpg, a file twice the size limit and a file named ../../marker.txt. All are refused, or stored under a random name that never runs. Fetching a stored upload returns nosniff, and attachment unless it is an image.
Sources
Related rules
- APP-24 Check files in the browser before they upload in Web app interface
- MED-41 Upload straight to storage with a signed address in Files and media
- MED-43 Confirm every upload on the server in Files and media
- MED-3 Serve user files from their own domain in Files and media
- MED-44 Scan files for malware before anyone opens them in Files and media
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/application-security/requests-files-and-caches/safe-file-uploads">Agent Wranglers application security playbook</a>. In code you write, add a comment next to it with the same link.