Skip to content

HTML5 Security - Cross Origin Requests

Cross Origin Requests heben den wichtigsten (um nicht zu sagen einzigen) Schutz der Webbrowser vor bösartigen JavaScript-Code teilweise auf: Die Same Origin Policy (die ich hier genauer erkläre). Sie verhindert, dass eingeschleuster Schadcode hemmungslos mit einem Server des Angreifers kommunizieren kann, stört mitunter aber auch bei harmlosen Anwendungen. HTML5 schafft dafür durch das Cross Origin Resource Sharing Abhilfe.

Cross Origin Requests

Ein Cross Origin Request (im folgenden als COR abgekürzt) kann nicht nur an die eigene Origin des ausführenden JavaScript-Codes, sondern an beliebige Origins, also Domains, geschickt werden. Der JavaScript-Code kann dann über die responseText-Property die Daten der Antwort abfragen.

Welchen Origins CORs erlaubt sind, wird vom Server im 'Access-Control-Allow-Origin'-Header in der Antwort auf einen COR festgelegt. Nur an die dort enthaltenen Origins gibt der Webbrowser die empfangenen Daten weiter. Wird dort die Wildcard '*' eingetragen, kann der Clientcode von jeder Website auf die Inhalte zugreifen und ein Angreifer kann unter Umständen sensitive Daten ausspähen.

Nehmen wir mal an, eine nur im Intranet eingesetzte Webanwendung verwendet als Wert für den 'Access-Control-Allow-Origin'-Header die Wildcard '*'. Im Intranet gibt es ja nur vertrauenswürdige Server, und egal von welchem davon ein Client JavaScript-Code lädt, dieser Code darf immer auf die Daten der Webanwendung zugreifen. Da ist so ein '*' doch viel einfacher als eine Liste erlaubter Origins, die dann womöglich auch noch gewartet werden muss.

Dieser Ansatz hat aber einen großen Nachteil: Gelingt es einem Angreifer, zum Beispiel über XSS Schadcode in den Webbrowser eines Benutzers einzuschleusen, kann der danach ungestört über CORs auf die Intranet-Webanwendung zugreifen.

Vorsicht vor dem 'Origin'-Header!

Auch dem in einem COR enthaltenen 'Origin'-Header sollten Sie im Zweifelsfall nicht vertrauen. Solange der vom Webbrowser gesetzt wurde, sollte er korrekt sein (eine mögliche Schwachstelle im Webbrowser mal außer Acht gelassen). Aber wer sagt denn, dass der COR unverfälscht und/oder von einem Webbrowser stammt? Wie alle vom Client gelieferte Daten kann auch der 'Origin'-Header des COR manipuliert sein.

Verwenden Sie den 'Origin'-Header also nicht für die Zugriffskontrolle, zum Beispiel nach folgenden Muster:

<?php
if ($_SERVER['HTTP_ORIGIN'] == "[vertrauenswürdiger Server]") {
   header('Access-Control-Allow-Origin: [vertrauenswürdiger Server]');
   // Ausgabe vertraulicher Informationen, die für den 
   // Clientcode des vertrauenswürdigen Server bestimmt sind
} else {
   // Ausgabe harmloser Informationen
}
?>

Bevor Sie sensitive Informationen ausgeben, authentifizieren Sie den Benutzer. Der Server kann die Authentifizierung durch einen 'Access-Control-Allow-Credentials'-Header in der Antwort auf den COR anfordern, der Client sollte darauf mit einem COR mit gesetztem 'Credentials'-Flag und den Zugangsdaten (Credentials) antworten. Tut er das nicht oder sind die Zugangsdaten falsch, könnte es sich um einen Angriff handeln.

'Access-Control-Allow-Origin'-Header ist kein Zugriffsschutz

An dieser Stelle noch eine kleine Klarstellung: Der 'Access-Control-Allow-Origin'-Header wird zwar vom Browser geprüft, und nur JavaScript-Code von den darin enthaltenen Origins wird der Zugriff auf die Daten erlaubt - aber dann befinden sich die Daten bereits auf dem Rechner des Angreifers. Er kann sie problemlos in einem Proxy abfangen, bevor sie den Browser erreichen. Oder im Proxy den Wert des 'Access-Control-Allow-Origin'-Headers durch einen '*' ersetzen. Oder seinen Browser so präparieren, dass der den 'Access-Control-Allow-Origin'-Header ignoriert. Oder...

Bevor als Antwort auf einen COR sensitive Daten gesendet werden, sollte der Benutzer authentifiziert werden. Das ist für normale HTTP-Requests üblich (bzw. sollte es sein), und die gleichen Regeln müssen für CORs verwendet werden.

Vertrauen ist gut, Kontrolle ist besser

Ebenso, wie der Server nicht blind dem Client vertrauen darf, sollte auch der Client der Antwort des Servers ggf. eine gewisse Skepsis entgegen bringen. Was ist, wenn der Server kompromittiert wurde und die Antwort falsch ist? Wenn die Daten wirklich wichtig sind, sollte ihre Authentizität geprüft werden. Auch wenn das nicht ganz einfach ist, denn normalerweise verwendet man dafür digitale Signaturen.

Werden die Daten auf dem Webserver erzeugt und dann signiert, kann der Angreifer nach der Kompromittierung des Servers und der Manipulation der Daten diese selbst signieren, der dafür benötigte geheime Schlüssel der Webanwendung muss für deren eigene Nutzung ja auf dem Server gespeichert sein. Nur Daten, die auf einem separaten Server erstellt und signiert wurden, sind vor einem solchen Angriff sicher (sofern dieser Server nicht ebenfalls kompromittiert wurde).

Cross Origin Requests in Angreiferhand

Was kann ein Angreifer mit einem COR anfangen? Im Grunde nichts, was er nicht zuvor auch schon konnte: Requests mit Daten darin an beliebige Server senden. Was früher nur über Tricks möglich war, wie in der Beschreibung der Same Origin Policy demonstriert, geht jetzt ohne Umwege.

Womit wir zu einem meiner Lieblingsthemen kommen. Ein Angreifer, der die Kontrolle über den Webbrowser hat, befindet sich im lokalen Netz. Dort gibt es meist noch viel interessantere Ziele als den aktuell angegriffenen Rechner, aber wie soll der Angreifer sie finden? Er müsste beispielsweise mit einem Portscanner nach Servern im lokalen Netz suchen. Aber woher bekommt er im Browser einen Portscanner? Den kann er sich einfach selbst bauen. Etwas JavaScript-Code reicht, und den kann er problemlos ausführen.

Das war schon vor HTML5 möglich, wird mit den Cross Origin Requests aber teilweise einfacher. Die Attack and Defense Labs haben das JavaScript-Tool JS-Recon entwickelt, dass Cross Origin Requests oder WebSockets verwendet, um im lokalen Netz nach Rechnern zu suchen. Da es sich um eine Beispielimplementierung handelt, können Sie die natürlich auch ausprobieren.

Mehr zu Cross Origin Requests erfahren Sie in meinem auf deutsch und englisch erhältlichen eBook "HTML5 Security". In der nächsten Folge geht es um eine weitere Kommunikationsmöglichkeit: WebSockets.

Carsten Eilers


Übersicht über alle Artikel zum Thema

HTML5 Security - Eine Einführung
HTML5 Security - SVG und Resident XSS
HTML5 Security - Formulare auf Abwegen
HTML5 Security - Gift für den Application Cache
HTML5 Security - Der Local Storage
HTML5 Security - Die SQL-Datenbank
HTML5 Security - Cross Origin Requests
HTML5 Security - Gefährliche WebSockets
HTML5 Security - postMessage() sicher nutzen

Trackbacks

Dipl.-Inform. Carsten Eilers am : Drucksache: Windows Developer 12.18 - Was tun gegen die REST-Unsicherheit?

Vorschau anzeigen
Im Windows Developer 12.18 ist ein Artikel über die Sicherheit der REST-Architektur erschienen. Gibt es beim REST, dem &quot;Representional State Transfer&quot; eigentlich irgend was zu schützen? Und wenn ja, wo und wie? Und wieso? Was is