Was kann verhindern, dass bösartiger Code den "Origin" -Header fälscht, um CORS auszunutzen?

142

So wie ich es verstehe, muss ein clientseitiges Skript, das auf einer Seite von foo.com ausgeführt wird, Daten von bar.com anfordern möchte, in der Anforderung den Header angeben Origin: http://foo.comund bar muss mit antworten Access-Control-Allow-Origin: http://foo.com.

Was kann verhindern, dass bösartiger Code von der Website roh.com einfach den Header fälscht Origin: http://foo.com, um Seiten von der Leiste anzufordern?

Jay Lamont
quelle
2
Ich glaube, der Punkt ist, dass die ursprüngliche Domain, von der aus die Seite (hier foo.com) bereitgestellt wird, den Access-Control-Allow-OriginHeader bereitstellen muss, sonst lässt der Browser die Anfrage nicht zu bar.com.
Chris Hayes
2
Das Lesen dieses Beitrags hat mir wirklich geholfen, den cors-Prozess zwischen Browser, Ursprungsserver und Zielserver zu verstehen. html5rocks.com/de/tutorials/cors
brendonparker
5
@ ChrisHayes So funktioniert CORS überhaupt nicht. Sie können dies etwas genauer nachlesen, indem Sie sich die Spezifikation oder diese großartige MDN-Wiki-Seite zu diesem Thema ansehen .
Ray Nicholus
1
@brendonparker Ja, das ist ein großartiger Artikel. Dieser Autor beantwortet viele CORS-Fragen zu SO und unterhält auch enable-cors.org .
Ray Nicholus
4
@ RayNicholus Interessant, ich war eindeutig weit weg. Danke für die Links. Nach den Stimmen in meinem Kommentar zu urteilen, bin ich nicht der einzige, der unter dieser Täuschung leidet. Ich hoffe, diese beiden kommen zurück und lernen (und entfernen ihre Stimmen!).
Chris Hayes

Antworten:

149

Browser haben die Kontrolle über das Festlegen des OriginHeaders, und Benutzer können diesen Wert nicht überschreiben. Sie werden also nicht sehen, dass der OriginHeader von einem Browser gefälscht wird. Ein böswilliger Benutzer könnte eine Curl-Anforderung erstellen, mit der der OriginHeader manuell festgelegt wird. Diese Anforderung kommt jedoch von außerhalb eines Browsers und enthält möglicherweise keine browserspezifischen Informationen (z. B. Cookies).

Denken Sie daran: CORS ist keine Sicherheit. Verlassen Sie sich nicht auf CORS, um Ihre Site zu sichern. Wenn Sie geschützte Daten bereitstellen, verwenden Sie Cookies oder OAuth-Token oder etwas anderes als den OriginHeader, um diese Daten zu sichern. Der Access-Control-Allow-OriginHeader in CORS gibt nur vor, welche Ursprünge Ursprungsübergreifende Anforderungen stellen dürfen. Verlassen Sie sich nicht mehr darauf.

Monsur
quelle
3
Das macht sehr viel Sinn. Wenn der Browser nicht zulässt, dass JavaScript den Origin-Header überschreibt, gibt es kein Problem. Wenn Sie Anforderungen von außerhalb des Browsers ausführen, werden die Cookies nicht angezeigt. Ich glaube, ich war verwirrt, weil in allen Dokumenten, die ich las, nirgends ausdrücklich gesagt wurde, dass der Origin-Header nicht überschrieben werden konnte. Vielen Dank!
Jay Lamont
41
Wenn jemand etwas fälschen möchte, kann er dies tun. Mit so ziemlich jeder Skriptsprache können sie http-Anfragen erstellen. Perl und Python haben http-Bibliotheken, die dies ziemlich einfach machen. In den Bibliotheken werden Cookies gespeichert und gesendet, Sie können beliebige Header hinzufügen und zahlreiche Debugging-Informationen bereitstellen. Die CORS-Header sollen es also nur für böswilliges Javascript in einem Forum, das Sie lesen, schwieriger machen, Ihrem Bankkonto in einer anderen Domain etwas Böses anzutun, wenn Sie in Ihrem Browser bei beiden angemeldet sind.
Mnebuerquo
9
Zur Verdeutlichung könnte der böswillige Benutzer einfach eine Browser-Instanz erzeugen, die gepatcht wurde, um die manuelle Kontrolle über den Origin-Header zu ermöglichen, und sich dann perfekt als normaler Benutzer, Cookies, AJAX und alle anderen ausgeben.
Jordan Rieger
10
"Browser haben die Kontrolle über das Setzen des Origin-Headers, und Benutzer können diesen Wert nicht überschreiben." Ich bin sicher, es ist sehr einfach, ein Tool wie Fiddler2 oder Charles zu verwenden, um die Header zu ändern, sobald die Anfrage den Browser verlässt.
Asa
3
Der böswillige Benutzer kann einfach eine Browser-Instanz erzeugen, die gepatcht wurde, um die manuelle Kontrolle über den Origin-Header zu ermöglichen. Wenn Sie Zugriff auf den Computer haben, können Sie einfach eine gepatchte Browser-Instanz erzeugen (klingt eigentlich nicht so einfach für mich), warum nicht einfach die Cookies direkt von der Festplatte lesen? Sie werden im Klartext gespeichert, den Sie kennen. Im wirklichen Leben ist Cross-Site-Scripting eine echte Bedrohung, während Ihr Angriffsszenario nur erfunden und unpraktisch ist.
Stijn de Witt
35

TLDR: Nichts hindert bösartigen Code daran, den Ursprung zu fälschen . In diesem Fall wird Ihr Server nie davon erfahren und auf die Anforderungen reagieren. Manchmal sind diese Anfragen teuer. Verwenden Sie CORS also nicht anstelle von Sicherheitsmaßnahmen.


Ich habe kürzlich mit CORS herumgespielt und mir die gleiche Frage gestellt. Ich habe festgestellt, dass der Browser möglicherweise intelligent genug ist, um eine gefälschte CORS-Anfrage zu erkennen, wenn er eine sieht, aber Ihr Server ist nicht so intelligent.

Das erste, was ich fand, war, dass der OriginHeader ein HTTP- verbotener Headername ist, der nicht programmgesteuert geändert werden kann. Das heißt, Sie können es in ca. 8 Sekunden mit " Header ändern" für Google Chrome ändern .

Um dies zu testen, habe ich zwei Client-Domänen und eine Server-Domäne eingerichtet. Ich habe eine CORS-Whitelist auf dem Server eingefügt, die CORS-Anforderungen von Client 1, aber nicht von Client 2 zuließ. Ich habe beide Clients getestet, und tatsächlich waren die CORS-Anforderungen von Client 1 erfolgreich, während Client 2 fehlgeschlagen ist.

Dann habe ich den OriginHeader von Client 2 gefälscht , damit er mit dem von Client 1 übereinstimmt. Der Server hat den gefälschten OriginHeader erhalten und die Whitelist-Prüfung erfolgreich bestanden (oder ist fehlgeschlagen, wenn Sie ein halb leerer Typ sind). Danach leistete der Server eine pflichtbewusste Leistung, indem er alle Ressourcen verbrauchte, für die er ausgelegt war (Datenbankaufrufe, Senden teurer E-Mails, Senden noch teurerer SMS-Nachrichten usw.). Als dies erledigt war, schickte der Server den gefälschten Access-Control-Allow-OriginHeader glücklich zurück an den Browser.

In der Dokumentation, die ich gelesen habe, heißt es, dass der Access-Control-Allow-Originempfangene OriginWert genau mit dem in der Anforderung gesendeten Wert übereinstimmen muss . Sie stimmten überein, daher war ich überrascht, als ich die folgende Meldung in Chrome sah:

XMLHttpRequest kann nicht geladen werden http://server.dev/test. Der Header 'Access-Control-Allow-Origin' hat einen Wert http://client1.dev , der nicht dem angegebenen Ursprung entspricht. Origin http://client2.dev ist daher kein Zugriff gestattet.

Die Dokumentation, die ich gelesen habe, scheint nicht korrekt zu sein. Auf der Registerkarte "Netzwerk" von Chrome werden sowohl die Anforderungs- als auch die Antwortheader deutlich als angezeigt. http://client1.devSie können jedoch an dem Fehler erkennen, dass Chrome den tatsächlichen Ursprung irgendwie kennt http://client2.devund die Antwort korrekt ablehnt. Was an dieser Stelle keine Rolle spielt, da der Server die gefälschte Anfrage bereits akzeptiert und mein Geld ausgegeben hat.

Nocturno
quelle
2
@ Nocturno, danke für das Beispiel. Lassen Sie mich nur meine Beobachtung hinzufügen. CORS bezieht sich auf Browsersicherheitsfunktionen. Wenn ein sicherer Browser von seinem ursprünglichen Zustand geändert wird, kann dies so interpretiert werden, dass dem Browser möglicherweise eine Sicherheitsfunktion fehlt.
Luka Žitnik
10
Überhaupt nicht brillant. Es geht völlig am Punkt von CORS vorbei. Wenn Sie in der Lage sind, Anfragen vom Computer des Benutzers abzufangen, können Sie einfach deren Cookies lesen, Keylogger, Virusses und all diese anderen realen Bedrohungen installieren. CORS dient dazu, ehrliche Benutzer, die auf Site A angemeldet sind, vor einem schädlichen Skript zu schützen, das irgendwie auf Site B injiziert wurde. Das Skript auf Site B (das ein Ausschnitt aus Javascript in einem Forumsbeitrag sein könnte, der von Site B nicht korrekt maskiert wurde) wird ausgeführt Aktionen auf Site A unter dem Konto des Benutzers (z. B. Löschen von Inhalten usw.) unter Verwendung des Sitzungscookies von Site A.
Stijn de Witt
3
Dies wird als Cross-Site-Scripting bezeichnet und kann ohne CORS durchgeführt werden, ohne jemals die Kontrolle über den Computer des Benutzers erlangen zu müssen. Das ist der springende Punkt. Es war keine Kontrolle über den Computer des Benutzers erforderlich, da der Browser bei Anfragen an Site A das Sitzungscookie automatisch zur Anfrage hinzufügte, sodass es wie eine gültige Anfrage des Benutzers selbst aussah, obwohl es tatsächlich von einem Skript auf einem anderen stammte Seite? ˅. Die Richtlinie "Gleicher Ursprung" verhindert dies und CORS wird verwendet, um Domänen auf die Whitelist zu setzen, denen Zugriff gewährt werden soll, obwohl sie sich auf einem anderen Ursprung befinden.
Stijn de Witt
3
@ Nocturno Ja, ich war vielleicht ein bisschen zu grob, tut mir leid. Ihr ursprünglicher Punkt steht. Die Same-Origin-Richtlinie ist eine Browsersicherheitsfunktion, und CORS ist ein Mechanismus, um diese Sicherheit zu schwächen, indem einige Domänen auf die Whitelist gesetzt werden. OP muss verstehen, dass das Spoofing des Origin-Headers als "Angriff" nicht wirklich praktikabel ist, da es Ihnen nichts bringt, was mit z. B. Curl nicht möglich ist.
Stijn de Witt
3
@ Nocturno Ich denke, deine Eröffnungsrede ist etwas irreführend. There's nothing stopping malicious code from spoofing the origin-> Ja, Javascript kann nicht eingestellt werden Origin. Ja, ein Benutzer kann seinen Browser ändern / Fiddler verwenden, um den Ursprung zu ändern, aber das ist nicht das, gegen das sich CORS verteidigt. Von Angreifern kontrollierte Websites können Origin nicht ändern, was alles ist, was zählt.
RJFalconer
12

Nur eine bescheidene Zusammenfassung:

F: Wird die Same Origin Policy (SOP) nur von Browsern erzwungen?
A: Ja. Für alle Anrufe, die Sie in einem Browser tätigen, wird die SOP definitiv vom Browser angewendet. Der Server überprüft möglicherweise den Ursprung der Anforderung oder nicht.

F: Wenn eine Anfrage nicht der SOP entspricht, blockiert der Browser sie?
A: Nein, es liegt außerhalb der Autorität von Browsern. Browser senden nur Ursprungsübergreifende Anfragen und warten auf die Antwort, um festzustellen, ob der Anruf vom Server über Access-Control- * Header als legitim signalisiert wird . Wenn der Server keinen Access-Control-Allow-OriginHeader zurücksendet, den Ursprung des Anrufers nicht zurücksendet oder *den Header nicht zurücksendet, unterlässt ein Browser lediglich die Antwort an den Anrufer.

F: Bedeutet das, dass ich nicht fälschen kann Origin?
A: Im Browser und bei Verwendung von Skripten können Sie nicht überschreiben, Originda dies in der Kontrolle des Browsers liegt. Wenn Sie sich jedoch selbst hacken möchten, können Sie die von Ihrem Browser ausgehenden Anrufe mithilfe von Browsererweiterungen oder anderen auf Ihrem Computer installierten Tools manipulieren. Sie können auch ausgeben HTTPAnrufe mit curl, Python, C#, etc. und die ändern OriginHeader Trick - Server.

F: Wenn ich also den Server durch Ändern austricksen kann Origin, bedeutet das, dass er CORSnicht sicher ist?
A: CORS per se schweigt über Sicherheit - dh Authentifizierung und Autorisierung von Anforderungen. Es liegt an den Servern, Anforderungen zu überprüfen und sie durch jeden Mechanismus, mit dem sie arbeiten, wie Cookies und Header, zu authentifizieren / zu autorisieren. Trotzdem kann es uns bei Angriffen wie XSS ein bisschen mehr schützen:

Beispiel: Angenommen, Sie haben sich auf Ihrer Website angemeldet und ein böswilliges Skript versucht, eine Anfrage an Ihre Bank-Website zu senden, um Ihr Guthaben abzufragen : ein Reflected XSS- Angriff. Ihre Bank-Website vertraut den Anmeldeinformationen, die von (hier im Namen Ihrer) Website stammen, sodass die Anfrage authentifiziert und eine HTTPAntwort auf den Schadcode ausgegeben wird. Wenn es Ihrer Bank-Website nicht darum geht, ihre Endpunkte mit anderen Ursprüngen zu teilen, wird dies nicht berücksichtigtAccess-Control-Allow-OriginHeader in der Antwort. Bei Eingang der Anforderung erkennt der Browser nun, dass es sich bei der Anforderung um eine Cross Origins-Anforderung handelt. Die Antwort zeigt jedoch nicht, dass der Server die Ressource (hier den Endpunkt der Kontostandabfrage) gerne für Ihre Website freigegeben hat. Es unterbricht also den Fluss, sodass das zurückgegebene Ergebnis niemals den Schadcode erreicht.

Alireza
quelle
Schön, besser / klarer als die akzeptierte Antwort IMO
3dGrabber