The Double‑MIME Bypass: How a Simple Header Trick Turned File Upload Into a ,000 Stored XSS Windfall

Listen to this Post

Featured Image

Introduction:

In the relentless cat‑and‑mouse game of web application security, file upload functionalities remain a critical attack vector. A recent bug bounty disclosure highlights a sophisticated bypass where a researcher manipulated MIME types to transform a seemingly benign file upload into a potent stored Cross‑Site Scripting (XSS) attack, earning a four‑figure reward. This technique underscores the critical importance of robust server‑side validation in modern web applications.

Learning Objectives:

  • Understand the role of MIME type validation in file upload security and how it can be subverted.
  • Learn to craft and test a “double MIME type” header payload to bypass client‑side and weak server‑side filters.
  • Develop mitigation strategies to harden file upload handlers against such manipulation and XSS payload delivery.

You Should Know:

1. Decoding MIME Types and The Vulnerability

At its core, a Multipurpose Internet Mail Extensions (MIME) type is a standard label that identifies the nature of a file. Servers and browsers use it to determine how to process data. A common security practice is to whitelist certain MIME types (e.g., image/jpeg, application/pdf) during file upload. The vulnerability arises when the validation logic is flawed—for instance, only checking for the presence of an allowed type in the `Content-Type` header rather than validating the entire header correctly.

Step‑by‑step guide explaining what this does and how to use it.
Step 1: Identify the Target Functionality. Locate any feature that allows file uploads (profile pictures, document uploads, attachments).
Step 2: Intercept the Request. Use a proxy tool like Burp Suite or OWASP ZAP to capture the HTTP POST request when uploading a legitimate file (e.g., a PDF).
Step 3: Analyze the Validation. Observe the `Content-Type` header of the request (e.g., Content-Type: application/pdf). Attempt to upload a file with an HTML payload but renamed to .pdf. If it’s blocked, the server likely performs some validation.

2. Crafting the “Double MIME” Payload

The breakthrough technique involves confusing the parser by injecting a second MIME type into the header. The payload `application/pdf,text/html` is the key. Some validation routines may only check the first part (application/pdf), finding it acceptable, while the browser or downstream processor might interpret the file based on the latter type (text/html), executing any embedded JavaScript.

Step‑by‑step guide explaining what this does and how to use it.
Step 1: Create a Malicious File. Craft an HTML file containing your XSS payload. `` is a common proof‑of‑concept.

echo '<script>alert("XSS")</script>' > malicious.html

Step 2: Rename and Intercept. Rename the file to have an allowed extension, e.g., malicious.pdf. Upload it and intercept the request in your proxy.
Step 3: Inject the Double Header. In the intercepted request, find the `Content-Type` header and modify it to: `Content-Type: application/pdf,text/html`
Step 4: Forward the Request. Send the modified request to the server and observe the response.

3. Bypassing Extension and Content Sniffing Defenses

Advanced systems may also check file extensions, magic bytes (file signatures), and use content‑sniffing protection headers. The double MIME attack can be part of a broader bypass chain.

Step‑by‑step guide explaining what this does and how to use it.
Step 1: Combine with Magic Byte Injection. To pass signature checks, prepend the bytes of a legitimate PDF (or image) to your HTML file. On Linux:

printf '%s\n' '%PDF-1.4' '<script>alert(1)</script>' > bypass.pdf

This creates a file that appears as a PDF to a magic byte checker but contains HTML/JS.
Step 2: Test with `file` Command. Verify the file’s detected type: file bypass.pdf. It may still be identified as PDF.
Step 3: Deploy Full Payload. Upload this combined file while using the double MIME type header in the request.

4. Server‑Side Testing and Validation Bypass

To ethically test your own applications, you can simulate the attack using `cURL` to understand server behavior.

Step‑by‑step guide explaining what this does and how to use it.
Step 1: Prepare a Test Server (Demo). Set up a simple Node.js/Express endpoint with weak validation.
Step 2: Craft the `cURL` Command. Use cURL to send the malicious payload directly.

curl -X POST https://vulnerable-app.com/upload \
-F "[email protected]" \
-H "Content-Type: application/pdf,text/html"

Step 3: Analyze Response. Check if the file is accepted and stored. Then, attempt to access the uploaded file via a direct URL to trigger the XSS.

5. Mitigation Strategies: Building an Impenetrable Upload Handler

Proper defense is multi‑layered and must be implemented server‑side.

Step‑by‑step guide explaining what this does and how to use it.
Step 1: Use a Strict Allow‑List. Maintain a strict, minimal allow‑list of MIME types and extensions. Validate that the header contains only the single, expected type.

 Python (Flask) Example
ALLOWED_MIMES = {'image/jpeg', 'image/png', 'application/pdf'}

def validate_mime(uploaded_file):
 Get MIME type using a reliable library (e.g., python-magic)
actual_mime = magic.from_buffer(uploaded_file.read(2048), mime=True)
uploaded_file.seek(0)  Reset cursor
 Check for exact match, not substring
return actual_mime in ALLOWED_MIMES

Step 2: Rename Files. Generate a random filename (e.g., UUID) and apply your own safe extension based on validated type.
Step 3: Store Files Securely. Serve uploaded files from a separate domain/subdomain (content-security-policy), with correct `Content-Type` headers and `X-Content-Type-Options: nosniff` to prevent browser sniffing.
Step 4: Sanitize Content. For certain file types (like SVGs, which are XML), implement proper sanitization before storage.

What Undercode Say:

  • Validation Logic Must Be Atomic and Strict: Checking for the presence of a good value is insufficient. Validation must affirm that the input matches exactly and only the expected pattern. The double MIME exploit is a classic case of “garbage in, sometimes action out,” where the parser and the validator interpret the input differently.
  • The Attacker’s Mindset is Iterative: This finding wasn’t luck; it was a methodical bypass of a common defense. Attackers chain minor flaws—a lenient parser here, missing content‑sniffing headers there—into a critical vulnerability. Defenders must think in chains as well, building defense‑in‑depth.

This successful bounty highlights a persistent gap in input validation logic. As application stacks grow more complex, with multiple libraries handling request parsing, the risk of inconsistent interpretation rises. Looking forward, we predict an increase in similar “semantic confusion” attacks targeting other headers and parsers (e.g., Accept, Charset). Furthermore, the integration of AI‑powered code generators that might produce inherently lenient validation logic could temporarily increase the prevalence of such flaws. The professionalization of bug bounty hunting ensures these subtle bypass techniques will continue to be found and weaponized, making rigorous, specification‑based validation more non‑negotiable than ever.

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Dhananjay Kumar – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky