Original-URL des Artikels: https://www.golem.de/news/cross-site-scripting-javascript-code-in-bilder-einbetten-1411-110264.html    Veröffentlicht: 03.11.2014 11:48    Kurz-URL: https://glm.io/110264

Cross-Site-Scripting

Javascript-Code in Bilder einbetten

Mittels eines Tricks lassen sich gültige GIF-Bilder erstellen, die Javascript-Code enthalten. Damit kann der Schutzmechanismus Content-Security-Policy ausgehebelt werden. Abhilfe schafft ein noch wenig verbreiteter HTTP-Header.

Der IT-Sicherheitsspezialist Ajin Abraham hat eine Datei erzeugt, die einen gültigen GIF-Header enthält, aber gleichzeitig Javascript ausführt. Die Methode geht auf eine Idee von Ange Albertini zurück. Mit solchen manipulierten GIF-Dateien lässt sich unter bestimmten Umständen auch auf Webseiten, die mittels Content Security Policy (CSP) geschützt sind, bösartiger Javascript-Code ausführen.

Content Security Policy ist ein mächtiges Werkzeug, um Cross-Site-Scripting-Lücken (XSS) zu verhindern. Dabei wird ein Header gesetzt, der dem Browser mitteilt, von welchen Servern er Javascript ausführen darf. Setzt ein Webentwickler Content Security Policy korrekt ein, sollte damit eigentlich die Ausnutzung aller Cross-Site-Scripting-Lücken verhindert werden.

In vielen Fällen erlauben moderne Webanwendungen das Hochladen von Bildern. Gelingt es, in ein Bild Javascript-Code einzufügen, dann wird in so einem Fall der Schutz von CSP umgangen. Denn das Bild kommt ja vom selben Server, von dem auch der legitime Javascript-Code stammt.

Gleichzeitig GIF-Bild und Javascript-Code

Ein GIF-Bild beginnt mit der Zeichenkette GIF89a. Anschließend werden die Breite und die Höhe des Bildes gespeichert. Hier setzt der Trick von Albertini an: Für die Breite kann - völlig in Übereinstimmung mit dem GIF-Format - der Wert 0x2f2a eingetragen werden. Das entspricht einem Bild von 10.799 Pixeln Breite, gleichzeitig sind es aber auch die ASCII-Werte der Zeichenfolge /*, womit in Javascript ein Kommentar eingeleitet wird. Der Rest des GIF-Headers kann mit gültigen Werten gefüllt werden. Wird die Datei als Javascript interpretiert, werden diese Daten ignoriert, da es sich um einen Kommentar handelt.

Am Ende des GIF-Bildes wird nun die Zeichenfolge */=1; eingefügt. Der Kommentar wird durch */ beendet und das =1; führt dazu, dass aus der GIF89a-Signatur vom Beginn der Datei ein gültiger Code wird. Javascript sieht nun folgenden Code:

GIF89a/*[Kommentar]*/=1;

Das wird fehlerfrei interpretiert, es wird lediglich der Variablen mit dem Namen GIF89a der Wert eins zugewiesen. Anschließend kann beliebiger weiterer Javascript-Code in die Datei eingefügt werden.

Der Vorteil dieser Methode: Selbst wenn ein Server beim Upload prüft, ob es sich bei einer hochgeladenen Datei tatsächlich um ein Bild handelt, wird sie vermutlich akzeptiert, denn sie enthält gültige GIF-Daten.

Javascript mit falschem MIME-Type

Das zugrundeliegende Problem ist letztendlich, dass Browser Javascript-Code auch dann ausführen, wenn sie mit dem falschen Dateityp gesendet werden. Bei der Dateiübertragung mittels HTTP wird vom Server im Header ein sogenannter MIME-Type mitgeschickt. Für Javascript lautet dieser beispielsweise application/x-javascript. Für ein GIF-Bild wiederum lautet der MIME-Type image/gif.

Da häufig Daten mit falschen MIME-Informationen ausgeliefert werden, gibt es in Browsern diverse Mechanismen, durch die fehlerhafte Angaben ignoriert werden. Der Browser versucht, die Daten trotz fehlerhaften MIME-Typs korrekt zu interpretieren. Wird eine Datei mittels eingefügt, wird sie als Javascript-Code ausgeführt, egal, mit welchem MIME-Type sie ausgeliefert wurde. Damit ein Angreifer den Code ausführen kann, benötigt er also immer noch eine Möglichkeit, eigenen HTML-Code in die Webseite einzufügen, also eine klassische XSS-Lücke auszulösen. Doch genau die Ausnutzung solcher Lücken sollte durch Content Security Policy ja verhindert werden.

X-Content-Type-Options: nosniff

Dass dies ein potenzielles Sicherheitsrisiko darstellt, ist schon länger bekannt. Microsoft hat mit dem Internet Explorer 9 einen inoffiziellen Header eingeführt. Setzt der Server den HTTP-Header X-Content-Type-Options: nosniff, so wird dem Browser signalisiert, dass der MIME-Type in jedem Fall respektiert werden soll. Javascript-Code in Bildern wird damit ignoriert.

Inzwischen hat auch Google die Auswertung dieses Headers in Chrome implementiert und es gibt Bemühungen, diesen im Rahmen der WhatWG als Standard zu definieren. Für Firefox gibt es einen experimentellen Patch. Github hat für die Unterstützung in Firefox eine Bounty von 1.000 Dollar ausgeschrieben.

In Tests von Golem.de verhielten sich Chrome und der Internet Explorer in Details unterschiedlich bei der Interpretation des Headers. So war es in Chrome immer noch möglich, ein Bild mit dem falschen MIME-Type anzuzeigen, beispielsweise ein GIF-Bild, welches als image/png ausgeliefert wird. Der Internet Explorer blockiert die Anzeige in diesem Fall. Sicherheitskritisch dürfte dieser Unterschied nicht sein. Ein als image/gif oder mit einem anderen fehlerhaften MIME-Type ausgeliefertes Javascript wurde jedoch von beiden Browsern korrekt blockiert.

Vollständiger Schutz nur mit nosniff

Webentwickler, die sich mittels Content Security Policy vor Cross-Site-Scripting-Angriffen schützen wollen, sollten auf jeden Fall auch den nosniff-Header mitschicken. Nur dann ist der Schutz, den CSP bietet, wirklich vollständig. Zu bedenken ist dabei, dass der Header von der jeweiligen Datei mitgeschickt werden muss. Es reicht also beispielsweise in PHP-Anwendungen nicht, wenn das PHP-Skript in seiner Ausgabe den nosniff-Header mitschickt. Es muss auch dafür gesorgt werden, dass Bilder und andere Dateien jeweils den Header mitsenden. Auf Apache-Webservern kann dies in der Datei .htaccess konfiguriert werden.  (hab)


Verwandte Artikel:
Statt GIF: Chromium erhält Support für animierte PNGs   
(15.03.2017, https://glm.io/126742 )
Government Hack: Hack on German Government via E-Learning Software Ilias   
(08.03.2018, https://glm.io/133231 )
Forensik Challenge: Lust auf eine Cyber-Stelle beim BND? Golem.de hilft!   
(13.03.2017, https://glm.io/126691 )
Monero: Werbeanzeigen mit verstecktem Kryptomining auch auf Youtube   
(29.01.2018, https://glm.io/132449 )
Cross-Site-Scripting: Sicherheitslücke bei Ebay zwei Monate offen   
(23.05.2014, https://glm.io/106694 )

© 1997–2019 Golem.de, https://www.golem.de/