---
title: "Can an uploaded text file open as a page? Add nosniff"
description: "The X-Content-Type-Options: nosniff header tells the browser to follow the Content-Type your server sent instead of guessing the type from the content, so a text/plain file with HTML in it stays text."
url: https://ihsanalapsi.dev/articles/x-content-type-options-nosniff
lang: en
date: 2026-11-07
updated: 2026-11-07
tags: ["App security", "Web development"]
author: Ihsan Alapsi (إحسان العبسي)
---
# Can an uploaded text file open as a page? Add nosniff

A user uploads a file called `notes.txt` to your site, and inside it are lines of HTML and a script. Your server serves it from the same domain, and if the browser decides it looks like a page, you now have a page you never wrote running under your site's name. This article explains why the browser may guess, and how to stop it with one header.

## What is MIME sniffing in the browser?

MIME sniffing is the browser reading the content of a response to decide its type, instead of following the Content-Type header your server sent.

[OWASP's HTTP Headers Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html) says this sniffing can transform non-executable MIME types into executable MIME types. In other words, a text file or an image may be handled by the browser as something it runs.

## What does X-Content-Type-Options: nosniff do?

X-Content-Type-Options is a response header that tells the browser the MIME types in the Content-Type header should be respected and not changed, and it has one value: `nosniff`.

```
X-Content-Type-Options: nosniff
```

According to [MDN's X-Content-Type-Options page](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options), the header does three things:

1. It blocks a request if its destination is `style` and the type is not `text/css`, or if its destination is `script` and the type is not a JavaScript MIME type.
2. It prevents sniffing for all other response types, so the browser uses the declared Content-Type without examining the content.
3. It stops the browser from treating a response as `text/html` when it is loaded in a browsing context and the Content-Type is absent or not an HTML type.

## How does the header protect uploaded files?

The header protects uploaded files because the browser shows them by the type your server sent: a text file stays text, even when it holds HTML.

The same MDN page gives this exact example: if a server sends a response with `Content-Type: text/plain` and `X-Content-Type-Options: nosniff`, the browser will not interpret it as HTML, even if the content contains HTML markup:

```
Content-Type: text/plain
X-Content-Type-Options: nosniff

<script>alert(document.domain)</script>
```

In the browser this response shows up as a line of text, and the script does not run.

## Why does Content-Type have to be right too?

Content-Type has to be right because `nosniff` makes the browser take it literally: a wrong type on a CSS or JavaScript file makes the browser block it.

OWASP's recommendation is two things together: set the Content-Type header correctly throughout the site, and add `X-Content-Type-Options: nosniff`. The same cheat sheet says the `charset` attribute is necessary to prevent XSS in HTML pages, with this example:

```
Content-Type: text/html; charset=UTF-8
```

And the MDN page says site security testers usually expect this header to be set, and the Content-Type header to be correct for all resources.

## Where do you start now?

Open a file a user uploaded to your site, plus one CSS file and one JavaScript file, and look at the response headers in the developer tools. If `X-Content-Type-Options: nosniff` is missing, add it to every response on the server, and check that each file goes out with its correct type before you ship, so a CSS file that was served with the wrong type does not stop loading.

If you are working through your security headers, see [CSP in Report-Only mode](/articles/csp-report-only-rollout) to limit who can run scripts on your page, and [setting up HSTS correctly](/articles/hsts-strict-transport-security). If you want a full test of your file uploads and the rest of the platform, [Muhassan](/muhassan) does that.

Does your site accept files from users? What type does it serve them back with?

## FAQ

**Is nosniff enough on its own?**

No. nosniff makes the browser follow the Content-Type you sent, so Content-Type has to be correct for every file on the site, which is what OWASP recommends.

**What happens to a CSS file served with the wrong type?**

With nosniff, the browser blocks a style request whose type is not text/css, and a script request whose type is not a JavaScript MIME type.

**Why does OWASP recommend a charset on HTML pages?**

The OWASP cheat sheet says the charset attribute in Content-Type is necessary to prevent XSS in HTML pages, and its example is text/html; charset=UTF-8.
