X-Content-Type-Options is an HTTP response header that has exactly one valid value: nosniff. It instructs the browser to strictly follow the MIME type declared in the Content-Type header and never attempt to guess the content type on its own. This prevents a category of attacks that exploit browser MIME type sniffing behavior.
Of all the security headers, X-Content-Type-Options is the simplest to understand and implement. It takes one line of configuration, has no complex directives, and there is essentially no reason not to use it. Yet a surprising number of websites still don't send it.
What Is MIME Type Sniffing and Why Browsers Do It
To understand why this header exists, you need a bit of history. In the early days of the web, many servers were poorly configured and sent incorrect Content-Type headers. A server might serve an HTML file as text/plain, or an image as application/octet-stream. If browsers had strictly followed the declared type, these pages would have rendered as raw text or triggered a download instead of displaying correctly.
To work around this, browsers started "sniffing" the actual content of files to determine the real type. The browser would look at the first few bytes of a response, check for known signatures (like <html> tags, image headers, or JavaScript patterns), and override the server's declared type if the content looked different. Internet Explorer was particularly aggressive about this. If IE detected something that looked like HTML or JavaScript inside a file served as text/plain, it would happily render or execute it.
This was a reasonable workaround for badly configured servers, but it created a serious security hole.
How MIME Sniffing Enables Attacks
Here is a concrete attack scenario that targets a WordPress site with file uploads:
Suppose your WordPress site allows users to upload profile pictures. Your upload handler checks the file extension and only allows .jpg, .png, and .gif. An attacker creates a file that starts with valid image headers (the first few bytes look like a proper JPEG) but contains JavaScript code embedded after the image header. They name it avatar.jpg and upload it.
Your server stores the file and serves it with Content-Type: image/jpeg. So far, everything looks correct. But now the attacker links to this file from a page, perhaps in a forum post or comment, using a script tag:
<script src="https://yoursite.com/uploads/avatar.jpg"></script>Without X-Content-Type-Options, a browser performing MIME sniffing might look at the file, notice it contains JavaScript-like content, and execute it as a script despite the image/jpeg content type. The attacker's JavaScript now runs in the context of your site, with access to your visitors' cookies and session data.
With the nosniff header, the browser respects the declared image/jpeg type and refuses to execute the file as JavaScript. The attack fails.
MIME Sniffing and WordPress Media Uploads
WordPress has a media upload system that handles a lot of files: images, PDFs, documents, audio, video. Each of these is served with a specific MIME type. The WordPress core already does some validation on uploads (checking file types against an allowed list, verifying file content matches the extension), but these checks are not foolproof.
Several factors make WordPress particularly relevant here:
- Multiple upload points: The media library, Gravity Forms, Contact Form 7, WooCommerce product images, bbPress forum attachments, and many other plugins all handle file uploads. Each one is a potential entry point for malicious files.
- User-generated content: On sites with membership or community features, you may allow relatively untrusted users to upload files. The more upload sources you have, the more important it is that the browser treats files exactly as declared.
- Plugin upload handlers: Not all plugins validate uploads as carefully as WordPress core. A poorly written plugin might accept files with mismatched types, creating exactly the conditions that MIME sniffing attacks exploit.
- Shared hosting environments: On shared hosting, files from other sites on the same server could potentially be served with incorrect headers. The
nosniffdirective adds a layer of defense regardless of server-side configuration quality.
The Simplest Security Header to Implement
Adding X-Content-Type-Options takes one line. There are no directives to choose between, no values to tune, and no risk of breaking functionality. Unlike CSP (which can break inline scripts), HSTS (which can lock you out if your certificate expires), or Referrer-Policy (which can affect analytics), X-Content-Type-Options has effectively zero downside.
For Apache (.htaccess or virtual host config):
Header always set X-Content-Type-Options "nosniff"For Nginx:
add_header X-Content-Type-Options "nosniff" always;Via PHP in WordPress:
add_action('send_headers', function() {
header('X-Content-Type-Options: nosniff');
});WordPress itself already sends X-Content-Type-Options: nosniff for admin pages and REST API responses since version 4.8. However, the front-end pages of most WordPress installations do not include this header unless you add it at the server level or via a security plugin.
How Modern Browsers Handle MIME Sniffing
Browser behavior has improved significantly over the years. Modern versions of Chrome, Firefox, Safari, and Edge are much less aggressive about MIME sniffing than browsers from the Internet Explorer era. Chrome, for example, already blocks scripts that have a non-script MIME type in many situations even without the nosniff header.
However, there are still edge cases where sniffing occurs, and older browsers may still be vulnerable. The nosniff header provides a clear, definitive instruction that removes all ambiguity. It's a best practice regardless of which browsers your visitors use.
Interaction with Other Security Headers
X-Content-Type-Options works well alongside other security headers and there are no conflicts to worry about:
- Combined with CSP, it provides defense in depth: CSP controls which sources are allowed, while
nosniffensures files from allowed sources are treated as their declared type. - With HSTS, you ensure encrypted connections, and with
nosniff, you ensure content integrity on top of that. - Unlike other headers,
nosniffdoes not interact with or override any other header. It's purely additive.
What InspectWP Checks
InspectWP checks whether your WordPress site sends the X-Content-Type-Options: nosniff header. Because this header has only one valid value and no configuration complexity, there is really no reason for it to be absent. If your site is missing this header, it's one of the quickest security wins you can achieve. Adding it takes less than a minute and provides meaningful protection against MIME-type confusion attacks, especially on sites that handle file uploads.