0x00 Why File Uploads Still Pay in Bug Bounty
If there’s one feature that looks harmless but hides teeth, it’s the file upload. Profile pictures, resumes, invoices, support tickets — users expect them, developers ship them fast, and security usually gets bolted on after the fact.
For companies, it’s not just technical risk — it’s trust. If attackers can host arbitrary files at company.com/uploads/
, the brand itself becomes a delivery mechanism for fraud. For hunters, that makes file uploads valuable. They’re common, easy to test, and the difference between a “blocked” upload and an exploitable one is often a single missed filter.
0x01 Common Protections and How They Fail
Developers know uploads are risky, so they wrap them in filters. The problem is those filters are usually shallow — and hunters specialize in breaking shallow defenses.
Extension Filtering
Intention: Only allow safe types (
.jpg
,.png
,.pdf
).Reality: Blacklists are brittle. Variants like
.php5
,.phtml
,.asa
, or double extensions (shell.php.jpg
) often sneak through. Some filters only check the last extension, others ignore case (.PhP
).
MIME Type Checks
Intention: Trust the
Content-Type
header.Reality: That header comes from the client. A PHP shell uploaded as
Content-Type: image/png
passes unless the server inspects the actual file.
Magic Bytes / File Signatures
Intention: Validate files by their first few bytes (e.g., JPEG starts with
FF D8 FF
).Reality: Polyglot files beat this. Prepend JPEG bytes to a PHP payload, and it passes the signature check while still executing server-side.
Content Inspection / Antivirus
Intention: Scan uploaded files for malicious content.
Reality: Encoding, compression, or archive nesting easily bypass naive scanners.
File Size Restrictions
Intention: Block oversized uploads to prevent DoS.
Reality: Does nothing to stop malicious content. Sometimes image conversion tools (e.g., ImageMagick) choke on crafted but “valid” small files.
Upload Path Controls
Intention: Store uploads outside the web root.
Reality: Misconfigs often allow direct access (
/uploads/shell.php
) or chaining with LFI to execute files anyway.
Lesson: Defenses built in isolation fail. Strong systems layer checks, sandbox files, and segregate storage. Weak ones rely on a single assumption — and that’s what hunters break.
0x02 File Upload Exploitation Techniques
Finding an upload form is only step one. The real game is slipping past filters. Most upload vulns fall when you apply the right bypass in the right place.
Extension Bypasses
Legacy extensions:
.php3
,.php4
,.php5
,.phtml
— many servers still treat them as PHP.Case sensitivity:
shell.PhP
,shell.PHp
bypass lazy regex.Double extensions:
shell.php.jpg
if only the last extension is checked.Separator tricks:
shell.asp;.jpg
,shell.php%00.jpg
(null byte truncation).
Pro move: load a list of variants into Burp Intruder and let it fuzz extensions against the filter.
Polyglot Files
Files that wear two identities at once.
Example: prepend a JPEG header to a PHP payload.
The validator sees
FF D8 FF
(JPEG magic bytes).The server still executes the PHP when requested.
Polyglots bypass signature checks while keeping execution intact.
MIME Type Bypasses
If the app trusts headers, you win.
POST /upload HTTP/1.1
Host: target.com
Content-Type: image/png
Content-Disposition: form-data; name="file"; filename="shell.php"
The body is PHP code. Declared as PNG. Many apps accept it.
Encoding & Null Byte Tricks
String checks like endswith('.jpg')
can be fooled:
shell.php%00.jpg
shell.php%20.jpg
shell.php/.jpg
Depending on parsing quirks, the server interprets it as .php
.
Direct Access to Upload Paths
If uploads are stored under web root:
Try browsing directly:
https://target.com/uploads/shell.php
.If blocked, pair with LFI to include the file indirectly.
Chaining with Other Vulns
File upload + LFI → RCE.
File upload + XSS (SVG/HTML) → stored XSS.
File upload + weak auth → persistent phishing host.
Hunter’s rule: if you control what gets uploaded, you’re halfway to exploitation. The rest is persistence — cycle extensions, test polyglots, play with encodings until something sticks.
0x03 Recon & Automation for File Uploading Vulnerabilities
File upload vulnerabilities are found by knowing where apps let users push content. Once you know the patterns, you’ll start spotting them everywhere.
Tip: grep recon wordlists for upload
, media
, file
, attachment
, doc
, img
, content
. Those paths are usually worth a probe.
Recon Signals
Recon signals often reveal subtle weaknesses even when an upload feature isn’t outright exploitable. Watch for telltale differences such as varying error messages between a benign .jpg
and a dangerous .php
, an “upload failed” response even though the file is still accessible in /uploads/
, inconsistent status codes, or predictable file paths like /uploads/filename.ext
. These small leaks can map the attack surface before you ever attempt an exploit.
Burp Suite Workflows
Burp Suite makes probing these signals efficient. Use Sniper to fuzz file extensions against a single parameter, or Cluster Bomb to combine extension and Content-Type
tests for deeper coverage. Pair these attacks with Logger++ to monitor response anomalies—shifts in status codes or content length—that confirm you’ve found a weak spot worth investigating.
Automation at Scale
Nuclei community templates include file upload checks:
nuclei -l hosts.txt -t nuclei-templates/vulnerabilities/file-upload/
Won’t catch every bypass, but highlights weak endpoints for deeper manual work.
Beyond the UI
Uploads aren’t always where you expect them. Mobile apps may quietly POST to hidden endpoints like /upload.php
, JavaScript bundles can reference obscure media APIs, and staging subdomains such as staging-files.company.com
often run with looser filters. Each of these locations can expose functionality that isn’t obvious from the main interface.
Effective recon is about persistence. Keep mapping every corner—following code references, inspecting network traffic, and testing secondary environments, until you uncover the upload door nobody else has checked.
0x04 Impact & Reporting
Finding an upload vuln is good. Proving its impact is what gets you paid. Triagers don’t reward “I uploaded a file” — they reward what that file allows.
High-Impact Exploits
RCE: the jackpot. Upload a shell (
<?php system($_GET['cmd']); ?>
) and you’ve pivoted from profile pic to full compromise.Server-side pivoting: RCE → lateral movement into internal services. This is how “avatar to takeover” reports land five figures.
Medium-Impact Exploits
Stored XSS: malicious SVG or HTML rendered in admin dashboards.
File inclusion chains: pair upload with LFI to turn a
.jpg
into execution.Phishing/brand abuse: host attacker-controlled HTML/JS on a trusted domain. Even without execution, brand trust collapses.
Low-Impact but Valid
DoS: oversized or malformed files crashing converters (e.g., ImageMagick bombs).
Information disclosure: upload endpoints exposing server paths, metadata, or logs.
Reporting Like a Pro
Proof of concept: never drop a real shell in production. Upload a harmless PoC file (e.g.,
toxsec_poc.txt
) or an HTML page that just says “ToxSec PoC.”Screenshots: show the end-to-end flow — upload, access, execution/trigger.
Explain bypass: highlight which filter failed (“extension blacklist blocked
.php
but allowed.phtml
”).Frame business impact: don’t just say “XSS possible.” Show how it leads to account takeover, customer phishing, or data theft.
Why Programs Pay
File uploads hit where companies are most vulnerable: user trust. If company.com/uploads/
can serve malware or host a shell, that’s headline risk. Programs know it — and they pay accordingly.
0x05 Final Thoughts
File upload bugs are classics because they sit at the crossroads of convenience and danger. Users demand them, developers rush them, and attackers profit from the cracks left in between.
For hunters, uploads are worth testing every time. They’re common, filters are rarely airtight, and the payouts scale directly with impact — from stored XSS all the way up to remote code execution.
For programs, the risk is more than technical. A single poisoned upload can erode brand trust overnight. Customers don’t care if it’s a misconfigured MIME check; they care that company.com/uploads/
just served them malware.
Rule of thumb: if the app accepts files, assume it’s exploitable until proven otherwise. One incomplete regex, one forgotten extension, and your profile picture becomes a foothold into the server.