CORS - Was ist die Motivation für die Einführung von Preflight-Anfragen?

366

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?

Jan Groth
quelle

Antworten:

323

Ich war einige Zeit verwirrt über den Zweck der Preflight-Anfrage, aber ich glaube, ich habe sie jetzt.

Die wichtigste Erkenntnis ist, dass Preflight-Anfragen keine Sicherheitssache sind . Sie sind eher eine Sache, die die Regeln nicht ändert .

Preflight-Anfragen haben nichts mit Sicherheit zu tun, und sie haben keinen Einfluss auf Anwendungen, die derzeit mit einem Bewusstsein für CORS entwickelt werden. Der Preflight-Mechanismus kommt vielmehr Servern zugute, die ohne Kenntnis von CORS entwickelt wurden, und fungiert als Überprüfung der Integrität zwischen dem Client und dem Server, dass beide CORS-fähig sind. Die Entwickler von CORS waren der Ansicht, dass es genügend Server gibt, die auf der Annahme beruhen, dass sie niemals empfangen werden, z. B. eine domänenübergreifende DELETE-Anfrage, dass sie den Preflight-Mechanismus erfunden haben, damit sich beide Seiten anmelden können. Sie waren der Meinung, dass die Alternative, die darin bestanden hätte, die domänenübergreifenden Anrufe einfach zu aktivieren, zu viele vorhandene Anwendungen beschädigt hätte.

Hier gibt es drei Szenarien:

  1. Alte Server, die sich nicht mehr in der Entwicklung befinden und vor CORS entwickelt wurden. Diese Server gehen möglicherweise davon aus, dass sie niemals eine domänenübergreifende DELETE-Anforderung erhalten. Dieses Szenario ist der Hauptnutznießer des Preflight-Mechanismus. Ja, diese Dienste könnten bereits von einem böswilligen oder nicht konformen Benutzeragenten missbraucht werden (und CORS ändert daran nichts), aber in einer Welt mit CORS bietet der Preflight-Mechanismus eine zusätzliche Überprüfung der Integrität, sodass Clients und Server dies nicht tun brechen, weil sich die zugrunde liegenden Regeln des Webs geändert haben.

  2. Server, die sich noch in der Entwicklung befinden, aber viel alten Code enthalten und für die es nicht machbar / wünschenswert ist, den gesamten alten Code zu prüfen, um sicherzustellen, dass er in einer domänenübergreifenden Welt ordnungsgemäß funktioniert. In diesem Szenario können sich Server schrittweise für CORS anmelden, z. B. indem sie sagen: "Jetzt erlaube ich diesen bestimmten Header", "Jetzt erlaube ich dieses bestimmte HTTP-Verb", "Jetzt erlaube ich Cookies / Authentifizierungsinformationen." gesendet "usw. Dieses Szenario profitiert vom Preflight-Mechanismus.

  3. Neue Server, die mit einem Bewusstsein für CORS geschrieben wurden. Laut Standard - Sicherheitspraktiken, hat der Server seine Ressourcen in dem Gesicht zu schützen jede eingehenden Anforderung - Server können nicht vertrauen Kunden nicht auf bösartige Dinge zu tun. Dieses Szenario profitiert nicht vom Preflight-Mechanismus : Der Preflight-Mechanismus bietet einem Server, der seine Ressourcen ordnungsgemäß geschützt hat, keine zusätzliche Sicherheit.

Michael Iles
quelle
12
Wenn dies der Fall ist, warum wird es bei jeder Anfrage gesendet? Eine Anforderung pro Server sollte ausreichen, um festzustellen, ob dem Server CORS bekannt ist.
Douglas Ferguson
3
Die Spezifikation enthält einen Preflight-Ergebnis-Cache im Browser. Obwohl es sich immer noch klobig und ineffektiv anfühlt, scheint es möglich zu sein, neue Server so zu konfigurieren, dass der Preflight auf unbestimmte Zeit zwischengespeichert wird.
Michael Cole
7
Ich bin damit einverstanden, dass Preflight-Anfragen nicht inhärent mit Sicherheit zusammenhängen, aber es scheint, dass die Verwendung von Preflight-Anfragen durch CORS definitiv aus Sicherheitsgründen erfolgt. Es ist mehr als nur eine Überprüfung der geistigen Gesundheit, um ein relativ harmloses Fehlerszenario zu verhindern. Wenn der Benutzeragent die Anforderung blind an den Server gesendet hat und fälschlicherweise davon ausgegangen ist, dass der Server CORS implementiert hat, würde er höchstwahrscheinlich Fälschungen von standortübergreifenden Anforderungen akzeptieren. Obwohl die Antwort mit Javascript nicht lesbar wäre, hat der Server möglicherweise bereits unerwünschte Maßnahmen ergriffen, z. B. das Löschen eines Kontos oder eine Banküberweisung.
Alexander Taylor
5
Das Problem ist, dass der Preflight-Ergebnis-Cache im Grunde genommen nutzlos ist, weil 1. er nur für die genaue Anforderung gilt, nicht für die gesamte Domain, sodass alle Anforderungen sowieso beim ersten Mal vorab geflogen werden. und 2. wie implementiert, ist es in den meisten Browsern auf 10 Minuten begrenzt, also nicht annähernd unbegrenzt.
Davidgoli
2
@VikasBansal Der vorhandene Server muss sich "anmelden" und sich bereit erklären, seine Ressourcen über die Ursprünge hinweg zu teilen, indem konfiguriert wird, wie er auf die Preflight-Optionsanforderung antwortet. Wenn sie die Preflight-Anfrage nicht explizit beantworten, gibt der Browser die eigentliche Anfrage nicht aus. Schließlich möchten nicht alle Server Ursprungsübergreifende Anfragen bearbeiten.
Kevin Lee
215

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ädlichen B.comObjekten navigieren , enthält diese Seite Javascript, an das versucht wird, eine DELETEAnfrage an zu senden A.com/account. Da der Benutzer angemeldet ist A.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 DELETEund den Server entscheiden lassen, wie er damit umgehen soll. Aber was ist, wenn A.comdas CORS-Protokoll nicht bekannt ist? Es könnte weitergehen und das Gefährliche ausführen DELETE. 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 DELETEAnfrage 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.comkann POSTzu A.commit 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 POSTweiterhin zulässig ist. Das kann den Status ändern und Daten löschen wie ein DELETE!

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/url1von einem Servertyp und Anforderungen A.com/url2von 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-Pathnur 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ügen Content-Typeoder 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."

Kevin Christopher Henry
quelle
20
Dies ist das beste Einführungsstück, das ich über CORS gelesen habe. Vielen Dank!
Kiv
4
Genial erklärt.
Pratz
4
Dies ist die beste Antwort, die ich zu diesem Thema gesehen habe. Sehr gut erklärt!
Alaboudi
3
CORS ist ein kniffliges Material, und dieser Beitrag beleuchtet einige versteckte Punkte
Stanislav Verjikovskiy
1
@Yos: Der Browser würde diese Cookies enthalten, da von Browsern erwartet wird, dass sie so funktionieren (wie in Standards wie RFC 6265 kodifiziert ). Unabhängig davon, ob ein Browser separate Prozesse für Registerkarten verwendet oder nicht, ist ein Implementierungsdetail, das das Senden von Cookies nicht verhindert.
Kevin Christopher Henry
51

Betrachten Sie die Welt der domänenübergreifenden Anfragen vor CORS. Sie können ein Standardformular POST ausführen oder ein scriptoder ein imageTag 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.

Monsur
quelle
Wie stellen Sie eine POST-Anfrage über das Skript / img-Tag?
freakish
2
Das kannst du nicht. Ich meinte , dass Sie könnte entweder ein Formular POST tun, OR tun Skript / img einen GET verwenden. Ich habe den Beitrag bearbeitet, um dies hoffentlich zu klären.
Monsur
Aha. Das macht Sinn.
freakish
5
Danke für die Antwort, das hat mein Bild sicherlich vervollständigt! Leider sehe ich den zentralen Punkt hinter Preflights immer noch nicht. Zu Ihrer Antwort: Was wäre eine " unerwartete Anfrage "? Wie wäre es in einer Nicht-Preflight-Welt unerwarteter / weniger sicher als in einer Preflight-Welt (z. B. mit einem verlorenen Preflight oder einem böswilligen Browser, der das Preflighting einfach „vergisst“)?
Jan Groth
7
Es gibt wahrscheinlich APIs, die sich auf die Richtlinie des Browsers mit demselben Ursprung stützen, um ihre Ressourcen zu schützen. Sie sollten zusätzliche Sicherheit haben, verlassen sich jedoch stattdessen auf die Richtlinie mit demselben Ursprung. Ohne den Preflight könnte ein Benutzer in einer anderen Domäne jetzt eine Anforderung an die API senden. Die API würde annehmen, dass die Anforderung gültig ist (da sie nichts von CORS weiß) und die Anforderung ausführen. Der Browser könnte verhindern, dass die Antwort den Benutzer erreicht, aber zu diesem Zeitpunkt ist der Schaden möglicherweise bereits angerichtet. Wenn die Anforderung ein PUT / DELETE war, wurde die Ressource möglicherweise aktualisiert oder gelöscht.
Monsur
37

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- DELETEAnfrage oder eine Cross-Origin-Anfrage mit X-Requested-WithHeader, 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.

Kornel
quelle
12
Dies sollte die akzeptierte Antwort gewesen sein. Es ist das eindeutigste und auf den Punkt. Im Wesentlichen besteht der einzige Punkt bei Preflight-Anforderungen darin, Pre-CORS-Webstandards in Post-CORS-Webstandards zu integrieren.
Chopper Draw Lion4
2
Ich mag diese Antwort, aber ich denke, es kann nicht der vollständige Grund sein ... Die "Vertrauensannahme" muss nur für Dinge gelten, die nur der Browser tun kann (insbesondere das Senden der Benutzerinformationen des Browsers auf seine Domain beschränkt - das heißt, Cookies). Wenn dies nicht Teil der Annahme wäre, könnte alles, was eine Cross-Origin-Browseranforderung tun kann, bereits von einem Drittanbieter-Nicht-Browser-Agenten ausgeführt werden, oder?
Fabio Beltramini
2
@FabioBeltramini Richtig, Nicht-Browser können alles senden, was sie wollen. Angriffe über Browser sind jedoch etwas Besonderes, da Sie die Browser anderer Personen dazu bringen können, Dinge von ihrer eigenen IP-Adresse aus mit ihren eigenen Cookies usw. zu tun
Kornel
Ich sehe das eigentliche Problem. Vielen Dank für die Kommentare und die Antwort von @FabioBeltramini und Kronel. Wenn die Überprüfung vor dem Flug nicht vorhanden ist, kann ein Angreifer JavaScript-Code auf seiner Website platzieren, der jedoch von den Computern vieler anderer Personen ausgeführt wird. Alle anderen Kunden, einschließlich mobiler Apps, sind schwierig, andere dafür einzustellen.
Xiao Peng - ZenUML.com
16

Hier ist eine andere Sichtweise mit Code:

<!-- hypothetical exploit on evil.com -->
<!-- Targeting banking-website.example.com, which authenticates with a cookie -->
<script>
jQuery.ajax({
  method: "POST",
  url: "https://banking-website.example.com",
  data: JSON.stringify({
    sendMoneyTo: "Dr Evil",
    amount: 1000000
  }),
  contentType: "application/json",
  dataType: "json"
});
</script>

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:

Eine einfache Ursprungsanforderung wurde als kongruent mit denen definiert, die von derzeit bereitgestellten Benutzeragenten generiert werden können, die dieser Spezifikation nicht entsprechen.

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 einem srcAttribut ein Cross-Origin-GET ohne Vorflug auslösen kann, wäre es nicht sicherheitsrelevant, vor dem Kampf auf "einfachen" XHRs zu verlangen.

Dylan Tack
quelle
1
@MilesRout: Telnet ist nicht Teil des Bedrohungsmodells, das durch Preflights gemindert werden soll. Preflight ist für Browser relevant, die 1) sich auf gespeicherte "Umgebungsbefugnisse" (z. B. Cookies) verlassen und 2) dazu verleitet werden können, diese Befugnisse von Dritten zu missbrauchen (z. B. Fälschung von standortübergreifenden Anfragen). Das verallgemeinerte Modell ist als verwirrtes Stellvertreterproblem bekannt .
Dylan Tack
Das ist das Problem mit der Umgebungsautorität, Sie können es jedoch immer missbrauchen.
Miles Rout
13

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.

Hirako
quelle
Stimmen Sie dem CSRF-Angriffsproblem zu, das bei "neuen Servern", die in der Antwort von @ michael-iles erwähnt werden, noch möglich ist.
Aal Gheez
Dies ist eine nützliche Beschreibung, deren Aufnahme an anderer Stelle wahrscheinlich sinnvoll wäre. Vielleicht möchten Sie es einer der MDN-Seiten hinzufügen?
Sideshowbarker
Aber warum führen einige Anfragen wie POST mit Content-Type-Text / Plain keine Anfrage vor dem Flug durch? In meinem Kopf sollte jede 'Schreib'-Anfrage (POST, PUT, DELETE) diese Anfrage vor dem Flug haben, wenn die Sicherheit ein Problem darstellt.
Israel Fonseca
POST mit Text / Plain wird als einfache Anforderung betrachtet. Beachten Sie, dass der Browser die Antwort nicht anzeigt, wenn der Ursprung nicht übereinstimmt (was der Fall wäre, wenn der Server nicht für CORS konfiguriert ist).
Hirako
Auf der angreifenden Seite gibt es interessante Dinge, die getan werden können, indem die Tatsache ausgenutzt wird, dass einfache Anfragen toleriert werden und von den meisten Browsern gesendet werden. zB das .
Hirako
3

Darüber hinaus schreibt die Spezifikation für HTTP-Anforderungsmethoden, die Nebenwirkungen auf Benutzerdaten verursachen können (insbesondere für andere HTTP-Methoden als GET oder für die POST-Verwendung mit bestimmten MIME-Typen), vor, dass Browser die Anforderung "vorab prüfen"

Quelle

Oliver Weichhold
quelle
2

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.

Aditi Garg
quelle
1

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.

Nipo
quelle
4
Sie missverstehen Access-Control-Allow-Origin. Das Fehlen dieses Headers verhindert nicht, dass der Browser Anforderungen sendet, sondern lediglich, dass JS die Daten in der Antwort lesen kann.
Dylan Tack
Könnten Sie dies erklären? "Das Fehlen dieses Headers hindert den Browser nicht daran, Anforderungen zu senden, sondern verhindert lediglich, dass JS die Daten in der Antwort lesen kann." Ich verstehe es nicht vollständig.
SiddharthBhagwan
@ DylanTack Guter Punkt. Ich frage mich jedoch, warum ein GET xhr nicht auch Preflight ist. Obwohl dies unwahrscheinlich ist, können GET-Anforderungen auch schädlich / datenmutierend sein. Da all dies mit CSRF gelöst werden könnte, scheint mir dies, dass der Browser Server übermäßig schützt, die zu nachlässig sind, um gängige Sicherheitspraktiken zu implementieren.
Peleg
Die akzeptierte Antwort erklärt es gut als "Nicht-Ändern der Regeln" (Abwärtskompatibilität mit Websites, die vor der Existenz von CORS erstellt wurden). Trotzdem ist es interessant, Code zu sehen, deshalb habe ich eine weitere Antwort mit einem Codebeispiel gepostet.
Dylan Tack
1

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-OriginHeader nicht setzen .

Beim Schreiben von Anforderungen (wie POST) wird der Schaden jedoch verursacht, wenn die Anforderung beim Webserver eintrifft. * Ein Webserver kann den OriginHeader ü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.

AndreKR
quelle