Security . 29 Aug 2025 . By Nessa

Content-Type Bypass

It all starts with a common assumption:

"If the browser says this file is an image, and the server says it’s an image - it must be an image."



In modern web applications, file upload is one of the most ubiquitous features - and one of the most abused. Attackers have been refining their bypass methods for years, and among the three fundamental techniques for breaking upload restrictions are:

- Extension-based bypasses - exploiting double extensions, special characters, and filename tricks.

- Content-Type manipulation - forging HTTP headers to deceive server-side checks.

- Magic byte exploitation - crafting file contents to mimic trusted formats.

In this article, we’ll focus on the second technique - bypasses through Content-Type manipulation - and explain how a single forged header can turn a harmless upload form into an attacker’s backdoor.


The illusion of trust

When you upload a file via a web form, the browser sends an HTTP request containing multiple headers - including Content-Type. This header is supposed to tell the server what type of file is being sent (image/jpeg, image/png, etc.).

Many backend implementations trust this header completely, especially if they rely on the framework’s built-in file handling without extra validation. The logic goes like this:

"If Content-Type says image/png, then we’ll treat it as an image."

But here’s the problem: attackers can send the request without using the browser at all - using tools like curl, Burp Suite, Postman, or custom scripts and set any Content-Type they want.


Disguised payloads

Imagine an upload form that only allows .jpg files.

On the server, the code checks:


An attacker can take a PHP webshell, name it shell.php, and send the request:

The server sees image/jpeg in the request headers and happily stores the file - even though the actual content is executable PHP. If the upload directory is web-accessible, the attacker just visits /uploads/shell.php and gains remote code execution.


Why it works

Content-Type in the upload request is not generated by magic. It’s provided by the client, and the server should never blindly trust it. If there’s no secondary check on the actual file content (via magic bytes or library-based parsing), the header alone becomes a free pass for malicious files.

This is why client-side restrictions (JavaScript validation, HTML accept attribute) do nothing against skilled attackers - they can forge the entire request offline.


How attackers test for it

Security testers often try:

- Uploading .php or .html files while setting Content-Type: image/png or image/jpeg.

- Using legitimate file extensions but injecting malicious code inside.

- Mixing types, such as sending an executable with Content-Type: text/plain.

If the server accepts and stores the file without verifying its content, the vulnerability is confirmed.


How to defend against it

1. Never trust Content-Type from the request

Instead, inspect the uploaded file server-side using libraries like:

- PHP: finfo_file() or mime_content_type()

- Python: python-magic

- Node.js: file-type

2. Validate actual file content

Check magic bytes - the signature in the first few bytes of the file - to confirm its real format.

3. Enforce post-validation processing

For images, load and re-encode them with an image library (ImageMagick, Pillow). This guarantees the stored file contains only image data.

4. Store files outside the web root

Serve them through controlled endpoints with strict HTTP headers (X-Content-Type-Options: nosniff, Content-Disposition: attachment).

5. Remove execution permissions in upload directories

On Apache/Nginx, configure the uploads folder to block script execution.


Final thoughts

Content-Type bypass is one of the oldest tricks in the attacker’s book — and still works in 2025, because too many developers confuse what the client says with what the file actually is.

Security comes from independent verification, not blind trust. If your file validation ends at Content-Type, you’re effectively asking the attacker:

"So, what’s in this file?" - and believing whatever they tell you.

For teams seeking more advanced detection and prevention, the a42.tech platform delivers automated upload testing, signature verification, and integrated SOC workflows - keeping both offensive and defensive teams ahead of evolving threats.


Test smarter. Detect faster. Stay ahead.

Don’t just keep up with trends - be prepared for them!

Test our platform and see how fast detection meets real security.