Last updated: April 29, 2026
File upload is deceptively simple to describe and catastrophic when wrong. The developer’s mental model: “user uploads file, we store it.” The reality: “user supplies arbitrary bytes to a server context with multiple possible interpretations, and we must choose the right one at every stage.” Each stage has its own rules. Mistakes compound.
Why this happens
A file is an attack surface at three junctures: parsing, storage, and serving. Developers mostly think about the first (can I parse it without crashing?) and barely about the third (how will it be served back?). Storage is often naive. Each juncture has distinct failure modes.
Additionally, “file” is polymorphic. A single byte stream can be simultaneously a valid image and a valid HTML page (polyglot files). Browsers may sniff content type and ignore your Content-Type header. CDNs may re-interpret. Image processing libraries may have RCE vulns that execute when parsing maliciously-crafted images. The “file” you received isn’t just one thing.
How it goes wrong
1. Unsafe filename extension
User uploads shell.php. Server saves as uploads/shell.php. Web server serves PHP files from uploads/. Attacker gets RCE via web-accessible PHP. Still happens in 2026 on misconfigured Apache/Nginx.
2. Content-type spoof
User uploads shell.php with Content-Type: image/jpeg. Server trusts Content-Type and renames to .jpg. Attacker later finds the file served as JPEG but browser/Apache misidentifies via magic bytes, or server includes it via require().
3. Content-type mismatch in serving
File stored. When served back: Server says Content-Type: image/jpeg. Browser sniffs magic bytes, determines it’s HTML. Renders as HTML — stored XSS from the upload.
4. Path traversal in filename
Attacker uploads ../../../../etc/cron.d/evil. Server uses filename as-is. File lands outside uploads/. Depending on permissions, takeover.
5. Image library vulnerabilities
Attacker uploads malicious TIFF/PNG. ImageMagick or libvips parses it. RCE via known CVEs in image libraries. “Image conversion” is a classic attacker target.
6. ZIP slip
Application extracts user-uploaded ZIP. ZIP contains entries with ../../../etc/passwd path. Extraction writes outside intended directory.
7. Archive bomb (decompression bomb)
1 MB ZIP decompresses to 10 GB. DoS by disk exhaustion or parser OOM.
8. Unrestricted size / rate
Attacker uploads 500 large files, exhausting disk or bandwidth. No rate limit, no quota.
9. Polyglot content
File is simultaneously valid JPEG (passes image validation) and valid JavaScript (passes CSP script-src if same-origin). Browser decides based on context.
10. XXE via upload
User uploads SVG, XML, or Office document containing XML. Parser processes XML with external entities enabled. SSRF or file read via XXE.
Why we look
File upload RCE is catastrophic — direct server compromise. File upload XSS is subtle but persistent because stored artifacts survive fixes. File upload DoS via archive bomb is cheap to execute. For red teams, any upload feature is a top-priority target.
Beyond technical severity, file uploads are common in SaaS: profile pictures, document attachments, CSV imports, email attachments, image galleries, ticket attachments. Every one of them is a potential weak point.
What we find
- No extension allow-list (any extension accepted)
- Extension allow-list but no content-type verification — attacker sends .jpg with PHP content
- Content-type check but based on Content-Type header — trivially spoofed
- No magic-byte verification
- Filename preservation including special characters (./\ null bytes)
- No size limit
- No quota per user / tenant
- Same domain serving uploads as the main app (cookies sent to upload paths)
- Unsanitized SVG rendering — SVG contains
Want this for your team?
Custom team training + practitioner advisory
Beyond the free academy — we run private workshops, vCISO advisory, and red-team exercises tailored to your stack. For Indian SMBs scaling past their first hire.
Book team training call Replies in 4 working hrs · India-only · Senior consultants