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.com
Objekten navigieren , enthält diese Seite Javascript, an das versucht wird, eine DELETE
Anfrage 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 DELETE
und den Server entscheiden lassen, wie er damit umgehen soll. Aber was ist, wenn A.com
das 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 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
kann POST
zu A.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 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/url1
von einem Servertyp und Anforderungen A.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ügen Content-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."