File Upload Validation
File upload validation must check content, not just names and headers: magic bytes, extension mapping, size caps, storage isolation, and processing sandboxing determine the blast radius.
Definition
Secure upload handling validates the actual byte content — sniffed type, size, image decodability — maps extensions to an allowlist, stores files outside the web root or in object storage with random names, and processes them in isolated workers. Client-side checks and trusting the filename or Content-Type are decorative.
Context and scope
Avatar and document upload endpoints, import pipelines, and any feature accepting user files. Pairs with path traversal and command injection risks in processing steps.
Common misconceptions
- Checking the extension is enough — attackers rename; content sniffing and double-extension server configs decide behavior
- Storing outside the web root is enough — parsers processing uploads remain attack surface: archive bombs, decompression size, codec exploits
- Client-side validation contributes security — it is UX; the server re-validates everything or the check does not exist
Anti-patterns
- Saving uploads under the web root with original filenames, serving them as same-origin executable content
- Trusting the browser-provided MIME type instead of sniffing magic bytes
- Unzipping archives without cumulative size limits, enabling decompression bombs
Related concepts
Related examples
Authoritative source
https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html
What it is
An uploaded file is attacker-controlled bytes that the server will store, serve, and process. Each stage has its own interpretation rules — web server MIME mapping, image parser, archive extractor — and validation must hold at the stage where the risk lives.
How it works
The server-side pipeline enforces order: cap size before reading fully, sniff content type from magic bytes, verify decodability for claimed types, generate a random server-side name, store in object storage or a non-executable directory with download-only headers, and process asynchronously in sandboxed workers with resource limits. Each stage fails closed rather than falling back to trusting the filename.
When to harden
Every upload surface, including CSV importers and less obvious channels like font or subtitle uploads. Serve unknown content with Content-Disposition attachment and a strict Content-Type, never guessing.
Pitfalls
SVG is HTML with angles: scripts inside uploaded SVG execute when served inline — sanitize or force download. Archive extraction multiplies size and path risks: cap cumulative output and verify member paths. Polyglot files satisfy multiple parsers; decide which parser runs and validate for that one.