Cross-Origin Resource Sharing ist ein Mechanismus, mit dem eine Webseite XMLHttpRequests an eine andere Domain (aus Wikipedia ) senden kann .
Ich habe in den letzten Tagen mit CORS herumgespielt und ich glaube, ich habe ein ziemlich gutes Verständnis dafür, wie alles funktioniert.
Bei meiner Frage geht es also nicht darum, wie CORS / Preflight funktioniert, sondern darum, warum Preflights als neuer Anforderungstyp entwickelt wurden . Ich sehe keinen Grund, warum Server A einen Preflight (PR) an Server B senden muss, um herauszufinden, ob die reale Anfrage (RR) akzeptiert wird oder nicht - es wäre sicherlich möglich, dass B RR ohne akzeptiert / ablehnt jede vorherige PR.
Nachdem ich einiges gesucht hatte, fand ich diese Information unter www.w3.org (7.1.5):
Um Ressourcen vor Ursprungsübergreifenden Anforderungen zu schützen, die nicht von bestimmten Benutzeragenten stammen konnten, bevor diese Spezifikation vorhanden war, wird eine Preflight-Anforderung gestellt, um sicherzustellen, dass die Ressource diese Spezifikation kennt.
Ich finde, das ist der am schwersten zu verstehende Satz aller Zeiten. Meine Interpretation (sollte es besser "Best Guess" nennen) ist, dass es darum geht, Server B vor Anforderungen von Server C zu schützen, denen die Spezifikation nicht bekannt ist.
Kann jemand bitte ein Szenario erklären / ein Problem zeigen, das PR + RR besser löst als RR allein?
Was war die Motivation für die Einführung von Preflight-Anfragen?
Preflight-Anforderungen wurden eingeführt, damit ein Browser sicher sein kann, dass es sich um einen CORS-fähigen Server handelt, bevor bestimmte Anforderungen gesendet werden. Diese Anfragen wurden als solche definiert, die sowohl potenziell gefährlich (Statusänderung) als auch neu waren (vor CORS aufgrund der Richtlinie für denselben Ursprung nicht möglich ). Die Verwendung von Preflight-Anforderungen bedeutet, dass Server sich für die neuen, möglicherweise gefährlichen Arten von Anforderungen, die CORS ermöglicht, anmelden müssen (indem sie ordnungsgemäß auf den Preflight reagieren).
Das ist die Bedeutung dieses Teils der Spezifikation : "Um Ressourcen vor Ursprungsübergreifenden Anforderungen zu schützen, die nicht von bestimmten Benutzeragenten stammen konnten, bevor diese Spezifikation vorhanden war, wird eine Preflight-Anforderung gestellt, um sicherzustellen, dass die Ressource diese Spezifikation kennt."
Kannst du mir ein Beispiel geben?
Stellen wir uns vor, ein Browser-Benutzer ist auf seiner Bankenseite unter angemeldet
A.com
. Wenn sie zu den schädlichenB.com
Objekten navigieren , enthält diese Seite Javascript, an das versucht wird, eineDELETE
Anfrage an zu sendenA.com/account
. Da der Benutzer angemeldet istA.com
, würde diese Anforderung, falls sie gesendet wird, Cookies enthalten, die den Benutzer identifizieren.Vor CORS hätte die Same Origin-Richtlinie des Browsers das Senden dieser Anforderung blockiert. Da der Zweck von CORS darin besteht, genau diese Art der Kommunikation zwischen den Ursprüngen zu ermöglichen, ist dies nicht mehr angemessen.
Der Browser könnte das einfach senden
DELETE
und den Server entscheiden lassen, wie er damit umgehen soll. Aber was ist, wennA.com
das CORS-Protokoll nicht bekannt ist? Es könnte weitergehen und das Gefährliche ausführenDELETE
. Es könnte angenommen worden sein, dass es aufgrund der Same Origin-Richtlinie des Browsers niemals eine solche Anfrage erhalten könnte und daher niemals gegen einen solchen Angriff gehärtet worden wäre.Um solche nicht CORS-fähigen Server zu schützen, muss der Browser nach dem Protokoll zunächst eine Preflight-Anforderung senden . Auf diese neue Art von Anforderung können nur CORS-fähige Server ordnungsgemäß reagieren, sodass der Browser weiß, ob das Senden der tatsächlichen Anforderung sicher ist oder nicht
DELETE
.Warum kann der Angreifer bei all dieser Aufregung um den Browser nicht einfach eine
DELETE
Anfrage von seinem eigenen Computer senden ?Sicher, aber eine solche Anfrage enthält nicht die Cookies des Benutzers. Der Angriff, den dies verhindern soll, beruht auf der Tatsache, dass der Browser zusammen mit der Anforderung Cookies (insbesondere Authentifizierungsinformationen für den Benutzer) für die andere Domain sendet.
Das klingt wie Cross-Site Request Forgery , wo ein Formular vor Ort
B.com
kannPOST
zuA.com
mit der Benutzer-Cookies und Schaden anrichten.Das stimmt. Eine andere Möglichkeit, dies auszudrücken, besteht darin, dass Preflight-Anforderungen erstellt wurden, um die CSRF-Angriffsfläche für nicht CORS-fähige Server nicht zu vergrößern.
Wenn ich mir jedoch die Anforderungen für "einfache" Anfragen ansehe, für die keine Preflights erforderlich sind, sehe ich, dass dies
POST
weiterhin zulässig ist. Das kann den Status ändern und Daten löschen wie einDELETE
!Das stimmt! CORS schützt Ihre Site nicht vor CSRF-Angriffen. Andererseits sind Sie ohne CORS auch nicht vor CSRF-Angriffen geschützt. Der Zweck von Preflight-Anfragen besteht lediglich darin, Ihr CSRF-Risiko auf das zu beschränken, was bereits in der Pre-CORS-Welt existiert.
Seufzer. OK, ich akzeptiere widerwillig die Notwendigkeit von Preflight-Anfragen. Aber warum müssen wir das für jede Ressource (URL) auf dem Server tun? Der Server verarbeitet entweder CORS oder nicht.
Bist du dir da sicher? Es ist nicht ungewöhnlich, dass mehrere Server Anforderungen für eine einzelne Domäne verarbeiten. Beispielsweise kann es vorkommen, dass Anforderungen
A.com/url1
von einem Servertyp und AnforderungenA.com/url2
von einem anderen Servertyp verarbeitet werden. Es ist im Allgemeinen nicht der Fall, dass der Server, der eine einzelne Ressource verwaltet, Sicherheitsgarantien für alle Ressourcen in dieser Domäne geben kann.Fein. Lassen Sie uns Kompromisse eingehen. Erstellen wir einen neuen CORS-Header, mit dem der Server genau angeben kann, für welche Ressourcen er sprechen kann, damit zusätzliche Preflight-Anforderungen an diese URLs vermieden werden können.
Gute Idee! Tatsächlich wurde der Header
Access-Control-Policy-Path
nur für diesen Zweck vorgeschlagen. Letztendlich wurde es jedoch aus der Spezifikation herausgelassen, anscheinend weil einige Server die URI-Spezifikation falsch implementiert haben, so dass Anforderungen an Pfade, die für den Browser sicher erschienen, auf den defekten Servern tatsächlich nicht sicher wären.War dies eine umsichtige Entscheidung, bei der die Sicherheit Vorrang vor der Leistung hatte und die Browser die CORS-Spezifikation sofort implementieren konnten, ohne vorhandene Server zu gefährden? Oder war es kurzsichtig, das Internet auf verschwendete Bandbreite und doppelte Latenz zu verurteilen, nur um Fehler auf einem bestimmten Server zu einem bestimmten Zeitpunkt auszugleichen?
Die Meinungen sind unterschiedlich.
Nun, zumindest werden Browser den Preflight für eine einzelne URL zwischenspeichern?
Ja. Obwohl wahrscheinlich nicht sehr lange. In WebKit-Browsern beträgt die maximale Preflight-Cache-Zeit derzeit 10 Minuten .
Seufzer. Wenn ich weiß, dass meine Server CORS-fähig sind und daher nicht den Schutz benötigen, den Preflight-Anfragen bieten, kann ich sie dann vermeiden?
Ihre einzige echte Option besteht darin, sicherzustellen, dass Sie die Anforderungen für "einfache" Anfragen erfüllen . Das kann bedeuten, dass Sie benutzerdefinierte Header weglassen, die Sie sonst einschließen würden (wie
X-Requested-With
), über die lügenContent-Type
oder mehr.Was auch immer Sie tun, Sie müssen sicherstellen, dass Sie über einen angemessenen CSRF-Schutz verfügen, da die CORS-Spezifikation nicht die Ablehnung "einfacher" Anforderungen, einschließlich der unsicheren, behandelt
POST
. In der Spezifikation heißt es : "Ressourcen, für die einfache Anforderungen eine andere Bedeutung als das Abrufen haben, müssen sich vor Fälschungen von standortübergreifenden Anforderungen schützen."quelle
Betrachten Sie die Welt der domänenübergreifenden Anfragen vor CORS. Sie können ein Standardformular POST ausführen oder ein
script
oder einimage
Tag verwenden, um eine GET-Anforderung auszugeben. Sie konnten keinen anderen Anforderungstyp als GET / POST erstellen und für diese Anforderungen keine benutzerdefinierten Header ausgeben.Mit dem Aufkommen von CORS standen die Spezifikationsautoren vor der Herausforderung, einen neuen domänenübergreifenden Mechanismus einzuführen, ohne die bestehende Semantik des Webs zu brechen. Sie entschieden sich dafür, indem sie den Servern die Möglichkeit gaben, sich für einen neuen Anforderungstyp anzumelden. Dieses Opt-In ist die Preflight-Anfrage.
Daher benötigen GET / POST-Anforderungen ohne benutzerdefinierte Header keinen Preflight, da diese Anforderungen bereits vor CORS möglich waren. Für jede Anforderung mit benutzerdefinierten Headern oder PUT / DELETE-Anforderungen ist jedoch ein Preflight erforderlich, da diese in der CORS-Spezifikation neu sind. Wenn der Server nichts über CORS weiß, antwortet er ohne CORS-spezifische Header, und die eigentliche Anforderung wird nicht gestellt.
Ohne die Preflight-Anforderung können Server unerwartete Anforderungen von Browsern sehen. Dies kann zu einem Sicherheitsproblem führen, wenn die Server nicht auf diese Art von Anforderungen vorbereitet sind. Mit dem CORS-Preflight können domänenübergreifende Anforderungen auf sichere Weise in das Web eingeführt werden.
quelle
Mit CORS können Sie mehr Header und Methodentypen angeben, als dies bisher mit Cross-Origin
<img src>
oder möglich war<form action>
.Einige Server könnten (schlecht) geschützt worden sein, mit der Annahme, dass ein Browser dies nicht tun kann, z. B. eine Cross-Origin-
DELETE
Anfrage oder eine Cross-Origin-Anfrage mitX-Requested-With
Header, sodass solche Anfragen "vertrauenswürdig" sind.Um sicherzustellen, dass der Server CORS wirklich unterstützt und nicht nur zufällig auf Anfragen reagiert, wird der Preflight ausgeführt.
quelle
Hier ist eine andere Sichtweise mit Code:
Vor CORS würde der oben genannte Exploit-Versuch fehlschlagen, da er gegen die Richtlinie mit demselben Ursprung verstößt. Eine auf diese Weise entworfene API benötigte keinen XSRF-Schutz, da sie durch das native Sicherheitsmodell des Browsers geschützt war. Für einen Pre-CORS-Browser war es unmöglich, einen originenübergreifenden JSON-POST zu generieren.
Jetzt kommt CORS auf den Markt - wenn eine Anmeldung bei CORS über den Vorflug nicht erforderlich wäre, würde diese Site plötzlich ohne eigenes Verschulden eine große Sicherheitslücke aufweisen.
Um zu erklären, warum einige Anfragen den Vorflug überspringen dürfen, wird dies durch die Spezifikation beantwortet:
Um dies zu entwirren, wird GET nicht vorgeflogen, da es sich um eine "einfache Methode" im Sinne von 7.1.5 handelt. (Die Header müssen auch "einfach" sein, um den Vorflug zu vermeiden). Die Rechtfertigung dafür ist, dass eine "einfache" GET-Anforderung mit Ursprung zwischen den beiden bereits ausgeführt werden könnte
<script src="">
( z. B. funktioniert JSONP). Da jedes Element mit einemsrc
Attribut ein Cross-Origin-GET ohne Vorflug auslösen kann, wäre es nicht sicherheitsrelevant, vor dem Kampf auf "einfachen" XHRs zu verlangen.quelle
Ich habe das Gefühl, dass sich die anderen Antworten nicht auf den Grund konzentrieren, warum der Kampf vor dem Kampf die Sicherheit erhöht.
Szenarien:
1) Mit Vorflug . Ein Angreifer fälscht eine Anfrage von der Website dummy-forums.com, während der Benutzer bei safe-bank.com authentifiziert ist.
Wenn der Server nicht nach dem Ursprung sucht und irgendwie einen Fehler aufweist, gibt der Browser eine Anfrage vor dem Flug aus, OPTION Methode. Der Server kennt nichts von diesem CORS, das der Browser als Antwort erwartet, so dass der Browser nicht fortfährt (überhaupt kein Schaden).
2) Ohne Vorflug . Ein Angreifer fälscht die Anforderung im selben Szenario wie oben. Der Browser gibt die POST- oder PUT-Anforderung sofort aus. Der Server akzeptiert sie und verarbeitet sie möglicherweise. Dies kann möglicherweise zu Schäden führen.
Wenn der Angreifer eine Anfrage direkt von einem zufälligen Host aus sendet, denkt er höchstwahrscheinlich an eine Anfrage ohne Authentifizierung. Das ist eine gefälschte Anfrage, aber keine xsrf-Anfrage. Der Server überprüft also die Anmeldeinformationen und schlägt fehl. CORS versucht nicht, einen Angreifer zu verhindern, der über die Anmeldeinformationen verfügt, um Anforderungen zu stellen, obwohl eine Whitelist dazu beitragen könnte, diesen Angriffsvektor zu reduzieren.
Der Pre-Flight-Mechanismus erhöht die Sicherheit und Konsistenz zwischen Clients und Servern. Ich weiß nicht, ob dies den zusätzlichen Handschlag für jede Anfrage wert ist, da das Caching dort nur schwer verwendbar ist, aber so funktioniert es.
quelle
Quelle
quelle
Anforderungen vor dem Flug sind für Anforderungen erforderlich, die den Status auf dem Server ändern können. Es gibt 2 Arten von Anfragen -
1) Anrufe, die den Status auf dem Server nicht ändern können (wie GET) - Der Benutzer erhält möglicherweise eine Antwort auf die Anforderung (wenn der Server nicht nach dem Ursprung sucht), aber wenn die anfordernde Domäne nicht zum Antwortheader hinzugefügt wird. Allow-Origin, der Browser zeigt dem Benutzer die Daten nicht an, dh die Anforderung wird vom Browser gesendet, aber der Benutzer kann die Antwort nicht anzeigen / verwenden.
2) Anrufe, die den Status auf dem Server ändern können (wie POST, DELETE) - Da in 1) der Browser nicht die Anforderung blockiert, sondern die Antwort, sollten Statusänderungsaufrufe nicht ohne vorherige Überprüfung erfolgen dürfen . Solche Aufrufe können Änderungen an einem vertrauenswürdigen Server vornehmen, der den Ursprung der Aufrufe nicht überprüft (Cross Site Request Forgery genannt), obwohl die Antwort an den Browser möglicherweise ein Fehler ist. Aus diesem Grund haben wir das Konzept von Pre-Flight-Anforderungen, die einen OPTIONS-Anruf tätigen, bevor Anrufe mit Statusänderung an den Server gesendet werden können.
quelle
Sind die vorgeflogenen Anfragen zur Leistung nicht ? Mit den Preflight-Anforderungen kann ein Client schnell erkennen, ob der Vorgang zulässig ist, bevor er eine große Datenmenge sendet, z. B. in JSON mit der PUT-Methode. Oder bevor Sie sensible Daten in Authentifizierungs-Headern über das Kabel übertragen.
Die Tatsache, dass PUT, DELETE und andere Methoden neben benutzerdefinierten Headern nicht standardmäßig zulässig sind (sie benötigen eine explizite Berechtigung mit "Access-Control-Request-Methoden" und "Access-Control-Request-Headern"), das klingt Genau wie eine doppelte Überprüfung, da diese Vorgänge mehr Auswirkungen auf die Benutzerdaten haben könnten, stattdessen GET-Anforderungen. Es klingt also wie:
"Ich habe gesehen, dass Sie standortübergreifende Anforderungen von http: //foo.example zulassen , ABER sind Sie sicher, dass Sie DELETE-Anforderungen zulassen? Haben Sie die Auswirkungen berücksichtigt, die diese Anforderungen auf die Benutzerdaten haben könnten?"
Ich habe die zitierte Korrelation zwischen den vorab geflogenen Anforderungen und den Vorteilen der alten Server nicht verstanden. Ein Webdienst, der vor CORS oder ohne CORS-Kenntnis implementiert wurde, erhält niemals eine standortübergreifende Anfrage, da seine Antwort zunächst nicht den Header "Access-Control-Allow-Origin" enthält.
quelle
In einem Browser CORS Unterstützung Leseanforderungen (wie GET) sind bereits durch die Same Origin Policy geschützt: Eine bösartige Website versucht , einen authentifizierte Cross-Domain - Antrag zu stellen (zum Beispiel auf die Konfigurationsoberfläche Internet - Banking - Website oder Routers des Opfers) nicht in der Lage sein, die zurückgegebenen Daten zu lesen, da die Bank oder der Router den
Access-Control-Allow-Origin
Header nicht setzen .Beim Schreiben von Anforderungen (wie POST) wird der Schaden jedoch verursacht, wenn die Anforderung beim Webserver eintrifft. * Ein Webserver kann den
Origin
Header überprüfen, um festzustellen, ob die Anforderung legitim ist. Diese Überprüfung wird jedoch häufig nicht implementiert, da entweder der Webserver keine Notwendigkeit hat für CORS oder der Webserver ist älter als CORS und geht daher davon aus, dass domänenübergreifende POSTs durch die Richtlinie mit demselben Ursprung vollständig verboten sind.Aus diesem Grund haben Webserver die Möglichkeit, sich für den Empfang domänenübergreifender Schreibanforderungen zu entscheiden .
* Im Wesentlichen die AJAX-Version von CSRF.
quelle