X-Content-Type-Options: HTTP-Security-Header zum Schutz vor Content-Sniffing

Einige Webbrowser verfügen über eine Funktionalität namens Content-/MIME-Sniffing. Eigentlich gut gemeint, kann diese Funktionalität aber auch von Angreifern missbraucht werden. Um dies zu verhindern, kann der HTTP-Security-Header X-Content-Type-Options eingesetzt werden.

X-Content-Type-Options - Beschreibung & Funktionsweise

Im Allgemeinen teilt der Webserver dem Webbrowser innerhalb der HTTP-Antwort mit, um welchen Content- bzw. MIME-Type es sicher bei der vom Webbrowser angefragten und vom Webserver ausgelieferten Ressource handelt. Nehmen wir an, wir haben eine Webseite, die eine JavaScript-Datei einbindet:

<body>
<p>Webseite</p>
<script type="text/javascript" src="test.js"></script>
</body>
HTML - Beispiel-Webseite

Der Webbrowser fragt nun diese JavaScript-Datei vom Webserver an:

GET /test.js HTTP/2
Host: www.beispiel.de
HTTP-Anfrage des Webbrowser für eine JavaScript-Datei

Daraufhin sendet der Webserver dem Webbrowser die angefragte JavaScript-Datei und teilt ihm den entsprechenden Content-Type mit:

HTTP/2 200 OK
date: Sun, 15 Mar 2020 14:30:45 GMT
content-type: application/javascript; charset=UTF-8
content-length: 2802
HTTP-Antwort für angefragte JavaScript-Datei

Der Webbrowser würde die JavaScrpt-Datei anschließend ausführen.

Nehmen wir nun an, dass serverseitig eine Fehlkonfiguration vorliegt und der Websserver die JavaScript-Datei anstatt mit application/javascript als text/plain ausliefert:

HTTP/2 200 OK
date: Sun, 15 Mar 2020 14:30:45 GMT
content-type: text/plain; charset=UTF-8
content-length: 2802
HTTP-Antwort für angefragte JavaScript-Datei mit text/plain

Ein Webbrowser mit Content-Sniffing-Funktionalität würde nun standardmäßig erst den Inhalt der gelieferten Datei untersuchen. Sollte der Webbrowser dabei feststellen, dass es sich bei der Datei mit hoher Wahrscheinlichkeint nicht um eine "Plain"-Datei, sondern JavaScript-Datei handelt, würde er die gelieferte Datei abweichend vom ausgewiesenen Content-Type als JavaScript interpretieren und ausführen.

Das Problem hierbei ist, dass diese gut gemeinte Funktionalität - speziell in Verbindung mit XSS-Lücken - auch missbraucht werden kann. Bspw. könnte ein Angreifer eine Grafikdatei, die schadhaften JavaScript-Code enthält, hochladen. Der Webbrowser würde ggf. bei seiner Analyse des Dateiinhalts feststellen, dass JavaScript-Code enthalten ist und diesen ausführen.

Hier kommt nun der X-Content-Type-Options-Header ins Spiel. Mit diesem HTTP-Header kann dem Webbrowser mitgeteilt werden, dass Content-Sniffing nicht erlaubt ist und der vom Webserver ausgewiesene Content-Type anzuwenden ist. Im HTTP-Antwort-Header würde das wie folgt aussehen:

HTTP/2 200 OK
date: Sun, 15 Mar 2020 14:30:45 GMT
content-type: text/plain; charset=UTF-8
content-length: 2802
x-content-type-options: nosniff
HTTP-Antwort mit X-Content-Type-Options

In diesem Beispiel würde der Webbrowser die JavaScript-Datei nicht mehr ausführen.

Beispiel - X-Content-Type-Options in Aktion

Als Beispiel dient eine Webseite, die zwei JavaScript-Dateien einbindet:

<body>
<p>Webseite</p>
<script type="text/javascript" src="sniff.js"></script>
<script type="text/javascript" src="nosniff.js"></script>
</body>
HTML - Beispiel-Webseite

Beide JavaScript-Dateien werden vom Webserver als text/plain ausgeliefert. Die HTTP-Antwort von nosniff.js enthält zusätzlich den X-Content-Type-Options-Header. Rufen wir diese Webseite in Firefox auf und sehen in die Entwicklerkonsole, lässt sich feststellen, dass nur die sniff.js ausgeführt wurde:

Beispiel für X-Content-Type-Options

Header-Einstellungen im Detail

Der X-Content-Type-Options-Header unterstützt nur die Einstellung nosniff:

nosniff
Die Angabe bewirkt, wie oben bereits beschrieben, dass Content-Sniffing seitens des Webbrowser deaktiviert wird. Zudem wird für ausgewählte Content-Types Cross-Origin-Read-Blocking (CORB) aktiviert.

Webbrowser-Unterstützung

Der X-Content-Type-Options-Header wird von allen gängigen Webbrowsern unterstützt (siehe caniuse.com).

X-Content-Type-Options-Header übertragen

Zum Übertragen des X-Content-Type-Headers bedarf es einer Anpassung des Webservers.

Apache:
In der Konfigurationsdatei von Apache oder in der .htaccess ist folgende Anweisung zu hinterlegen:

Header always set X-Content-Type-Options "nosniff"
Apache-Konfigurationsdatei bzw. .htacess

nginx:
Analog dazu ist für nginx in der Konfigurationsdatei Folgendes einzufügen:

add_header X-Content-Type-Options "nosniff";
nginx-Konfigurationsdatei

X-Content-Type-Options-Einstellung von coding.blatt

Für meinen Blog wird für alle Ressourcen der X-Content-Type-Header mit nosniff gesetzt.

Fazit

Neben den anderen bereits vorgestellten HTTP-Security-Headern ist der Einsatz von X-Content-Type-Options ein weiterer einfach zu implementierender Baustein zur Erhöhung der Website-Sicherheit.

Feedback

Für Feedback zum Beitrag, seien es Fragen, Korrigierungen und/oder Anregungen, könnt ihr mir gerne eine Nachricht per E-Mail oder Mastodon schreiben (siehe Kontakt).