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.
Ü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