tl; dr - Am Ende finden Sie eine Zusammenfassung und Überschriften in der Antwort, um das Auffinden der relevanten Teile zu erleichtern. Es wird jedoch empfohlen, alles zu lesen, da es nützliche Hintergrundinformationen zum Verständnis des Warum bietet , wodurch es einfacher wird, zu sehen, wie das Wie unter verschiedenen Umständen angewendet wird.
Informationen zur Richtlinie für denselben Ursprung
Dies ist das gleiche Ursprungsrichtlinie . Es ist eine Sicherheitsfunktion, die von Browsern implementiert wird.
Ihr spezieller Fall zeigt, wie es für XMLHttpRequest implementiert ist (und Sie erhalten identische Ergebnisse, wenn Sie fetch verwenden), aber es gilt auch für andere Dinge (wie Bilder, die auf a geladen werden) <canvas>
oder in ein geladenes Dokument geladen werden <iframe>
), nur mit leicht unterschiedliche Implementierungen.
(Seltsamerweise gilt dies auch für CSS-Schriftarten, aber das liegt daran, dass Found Foundries auf DRM bestanden und nicht auf den Sicherheitsproblemen, die in der Same Origin Policy normalerweise behandelt werden.)
Das Standardszenario, das die Notwendigkeit der SOP demonstriert, kann mit drei Zeichen demonstriert werden :
- Alice ist eine Person mit einem Webbrowser
- Bob betreibt eine Website (
https://www.[website].com/
in Ihrem Beispiel)
- Mallory betreibt eine Website (
http://localhost:4300
in Ihrem Beispiel)
Alice ist bei Bob angemeldet und hat dort einige vertrauliche Daten. Möglicherweise handelt es sich um ein Unternehmens-Intranet (nur für Browser im LAN verfügbar) oder um ihr Online-Banking (nur mit einem Cookie verfügbar, das Sie nach Eingabe eines Benutzernamens und eines Kennworts erhalten).
Alice besucht Mallorys Website mit JavaScript, wodurch Alices Browser eine HTTP-Anfrage an Bobs Website sendet (von ihrer IP-Adresse mit ihren Cookies usw.). Dies kann so einfach sein wie das Verwenden XMLHttpRequest
und Lesen desresponseText
.
Die Same Origin-Richtlinie des Browsers verhindert, dass JavaScript die von Bobs Website zurückgegebenen Daten liest (auf die Mallory von Bob und Alice nicht zugreifen soll). (Beachten Sie, dass Sie zum Beispiel ein Bild anzuzeigen unter Verwendung eines <img>
Elements über Herkunft , weil der Inhalt des Bildes nicht auf JavaScript (oder Mallory) ausgesetzt ist ... es sei denn , Sie Leinwand in die Waagschale werfen , in dem Fall , dass Sie wird erzeugen ein gleich Herkunft Verstoßfehler).
Warum die Richtlinie für denselben Ursprung gilt, wenn Sie nicht der Meinung sind, dass dies der Fall sein sollte
Für eine bestimmte URL ist es möglich, dass die SOP nicht benötigt wird. Einige gängige Szenarien, in denen dies der Fall ist, sind:
- Alice, Bob und Mallory sind dieselbe Person.
- Bob stellt vollständig öffentliche Informationen zur Verfügung
… Aber der Browser kann nicht wissen, ob eine der oben genannten Aussagen zutrifft. Daher erfolgt das Vertrauen nicht automatisch und die SOP wird angewendet. Die Erlaubnis muss ausdrücklich erteilt werden, bevor der Browser die Daten, die er erhalten hat, an eine andere Website weitergibt.
Warum die Richtlinie für denselben Ursprung nur für JavaScript auf einer Webseite gilt
Browsererweiterungen *
, die Registerkarte Netzwerk in Browser-Entwicklertools und Anwendungen wie Postman sind installierte Software. Sie geben keine Daten von einer Website an das JavaScript einer anderen Website weiter, nur weil Sie diese andere Website besucht haben . Die Installation von Software erfolgt normalerweise bewusster.
Es gibt keinen Dritten (Mallory), der als Risiko eingestuft wird.
*
Browser-Erweiterungen müssen sorgfältig geschrieben werden, um Probleme zwischen verschiedenen Ursprüngen zu vermeiden. Siehe zum Beispiel die Chrome-Dokumentation .
Warum Sie Daten auf der Seite anzeigen können, ohne sie mit JS zu lesen
Es gibt eine Reihe von Umständen, unter denen Mallorys Website dazu führen kann, dass ein Browser Daten von einem Drittanbieter abruft und anzeigt (z. B. durch Hinzufügen eines <img>
Elements zum Anzeigen eines Bildes). Es ist Mallorys JavaScript jedoch nicht möglich, die Daten in dieser Ressource zu lesen. Dies können nur Alices Browser und Bobs Server. Daher ist es immer noch sicher.
CORS
Der Access-Control-Allow-Origin
HTTP - Antwort - Header bezeichnete in der Fehlermeldung ist Teil des CORS - Standard, den Bob Erlaubnis Mallorys Website ausdrücklich erteilen , die Daten über Alices Browser zugreifen kann.
Eine grundlegende Implementierung würde nur Folgendes umfassen:
Access-Control-Allow-Origin: *
… In den Antwort-Headern, damit jede Website die Daten lesen kann.
Access-Control-Allow-Origin: http://example.com/
… Würde nur einer bestimmten Site den Zugriff darauf ermöglichen, und Bob kann diese basierend auf dem Origin
Anforderungsheader dynamisch generieren, um mehreren, aber nicht allen Sites den Zugriff darauf zu ermöglichen.
Die Einzelheiten, wie Bob diesen Antwortheader festlegt, hängen vom HTTP-Server und / oder der serverseitigen Programmiersprache von Bob ab. Es gibt eine Sammlung von Handbüchern für verschiedene gängige Konfigurationen , die hilfreich sein können.
NB: Einige Anforderungen sind komplex und senden eine Preflight- OPTIONS-Anforderung, auf die der Server antworten muss, bevor der Browser die GET / POST / PUT / Whatever-Anforderung sendet, die der JS stellen möchte. Implementierungen von CORS, die nur Access-Control-Allow-Origin
zu bestimmten URLs hinzugefügt werden , werden häufig dadurch ausgelöst.
Offensichtlich würde Bob die Erlaubnis nur über CORS erteilen, wenn entweder:
- Die Daten waren nicht privat oder
- Mallory wurde vertraut
Aber ich bin nicht Bob!
Es gibt keinen Standardmechanismus für Mallory , um diesen Header hinzuzufügen, da er von Bobs Website stammen muss, die sie nicht kontrolliert.
Wenn Bob eine öffentliche API ausführt, gibt es möglicherweise einen Mechanismus zum Aktivieren von CORS (möglicherweise durch Formatieren der Anforderung auf eine bestimmte Weise oder eine Konfigurationsoption nach dem Anmelden bei einer Developer Portal-Site für Bobs Site). Dies muss jedoch ein von Bob implementierter Mechanismus sein. Mallory könnte die Dokumentation auf Bobs Website lesen, um zu sehen, ob etwas verfügbar ist, oder sie könnte mit Bob sprechen und ihn bitten, CORS zu implementieren.
Fehlermeldungen mit der Angabe "Antwort für Preflight"
Einige Cross-Origin-Anfragen werden vorab geflogen .
Dies geschieht, wenn Sie (grob gesagt) versuchen, eine originensübergreifende Anfrage zu stellen, die:
- Enthält Anmeldeinformationen wie Cookies
- Konnte nicht mit einem normalen HTML-Formular generiert werden (z. B. mit benutzerdefinierten Headern oder einem Inhaltstyp, den Sie in einem Formular nicht verwenden konnten
enctype
).
Wenn Sie etwas richtig machen, das einen Preflight benötigt
In diesen Fällen dann der Rest dieser Antwort gilt nach wie vor , aber sie auch sicherstellen müssen , dass der Server für die Preflight - Anfrage hören kann (was sein OPTIONS
(und nicht GET
, POST
oder was auch immer Sie senden versuchten) und reagieren auf sie mit der rechten Access-Control-Allow-Origin
Header aber auch Access-Control-Allow-Methods
und Access-Control-Allow-Headers
um Ihre spezifischen HTTP-Methoden oder Header zuzulassen.
Wenn Sie versehentlich einen Preflight auslösen
Manchmal machen die Leute Fehler, wenn sie versuchen, Ajax-Anfragen zu erstellen, und manchmal lösen diese die Notwendigkeit eines Preflights aus. Wenn die API Ursprungsübergreifende Anforderungen zulässt, jedoch nichts erfordert, was einen Preflight erfordern würde, kann dies den Zugriff unterbrechen.
Häufige Fehler, die dies auslösen, sind:
- versuchen,
Access-Control-Allow-Origin
und andere CORS-Antwortheader auf die Anfrage zu setzen. Diese gehören nicht zur Anfrage, tun nichts Hilfreiches (was wäre der Punkt eines Berechtigungssystems, an dem Sie sich selbst die Erlaubnis erteilen könnten?) Und dürfen nur in der Antwort erscheinen.
- Es wird versucht, einen
Content-Type: application/json
Header auf eine GET-Anforderung zu setzen, die keinen Anforderungshauptteil hat, um den Inhalt von zu beschreiben (normalerweise, wenn der Autor Content-Type
und verwirrt Accept
).
In beiden Fällen reicht das Entfernen des zusätzlichen Anforderungsheaders häufig aus, um die Notwendigkeit eines Preflights zu vermeiden (wodurch das Problem bei der Kommunikation mit APIs gelöst wird, die einfache Anforderungen, jedoch keine Preflight-Anforderungen unterstützen).
Undurchsichtige Antworten
Manchmal müssen Sie eine HTTP-Anfrage stellen, aber Sie müssen die Antwort nicht lesen. Beispiel, wenn Sie eine Protokollnachricht zur Aufzeichnung an den Server senden.
Wenn Sie die fetch
API verwenden (anstatt XMLHttpRequest
), können Sie sie so konfigurieren, dass sie nicht versucht, CORS zu verwenden.
Beachten Sie, dass Sie damit nichts tun können, was CORS tun muss. Sie können die Antwort nicht lesen. Sie können keine Anfrage stellen, für die ein Preflight erforderlich ist.
Sie können eine einfache Anfrage stellen, die Antwort nicht sehen und die Entwicklerkonsole nicht mit Fehlermeldungen füllen.
Wie das geht, wird in der Chrome-Fehlermeldung erläutert, die angezeigt wird, wenn Sie eine Anfrage mit stellen fetch
und keine Berechtigung zum Anzeigen der Antwort mit CORS erhalten:
Der Zugriff auf das Abrufen von " https://example.com/
vom Ursprung" https://example.net
wurde durch die CORS-Richtlinie blockiert: In Access-Control-Allow-Origin
der angeforderten Ressource ist kein " " Header vorhanden. Wenn eine undurchsichtige Antwort Ihren Anforderungen entspricht, setzen Sie den Anforderungsmodus auf "no-cors", um die Ressource mit deaktiviertem CORS abzurufen.
So:
fetch("http://example.com", { mode: "no-cors" });
Alternativen zu CORS
JSONP
Bob könnte die Daten auch mithilfe eines Hacks wie JSONP bereitstellen. Auf diese Weise haben die Leute Ajax übergreifend hergestellt, bevor CORS hinzukam.
Es funktioniert, indem die Daten in Form eines JavaScript-Programms dargestellt werden, das die Daten in Mallorys Seite einfügt.
Es erfordert, dass Mallory Bob vertraut, um keinen schädlichen Code bereitzustellen.
Beachten Sie das allgemeine Thema: Die Site, die die Daten bereitstellt, muss dem Browser mitteilen, dass es für eine Site eines Drittanbieters in Ordnung ist, auf die Daten zuzugreifen, die sie an den Browser sendet.
Da JSONP ein <script>
Element anfügt , um die Daten in Form eines JavaScript-Programms zu laden, das eine bereits auf der Seite vorhandene Funktion aufruft, schlägt der Versuch, die JSONP-Technik für eine URL zu verwenden, die JSON zurückgibt, fehl - normalerweise mit einem CORB-Fehler - aufgrund von JSON ist kein JavaScript.
Verschieben Sie die beiden Ressourcen zu einem einzigen Ursprung
Wenn sich das HTML-Dokument, in dem der JS ausgeführt wird, und die angeforderte URL auf demselben Ursprung befinden (dasselbe Schema, denselben Hostnamen und denselben Port verwenden), erteilt die Richtlinie für denselben Ursprung standardmäßig die Berechtigung. CORS wird nicht benötigt.
Ein Proxy
Mallory konnte serverseitigen Code verwenden, um die Daten abzurufen (die sie dann wie gewohnt über HTTP von ihrem Server an Alices Browser weiterleiten konnte).
Es wird entweder:
- CORS-Header hinzufügen
- Konvertieren Sie die Antwort in JSONP
- existieren auf demselben Ursprung wie das HTML-Dokument
Dieser serverseitige Code kann von einem Dritten (z. B. CORS Anywhere) geschrieben und gehostet werden. Beachten Sie die Auswirkungen auf den Datenschutz: Der Dritte kann überwachen, wer was auf seinen Servern vertritt.
Bob würde dafür keine Berechtigungen erteilen müssen.
Hier gibt es keine Auswirkungen auf die Sicherheit, da dies nur zwischen Mallory und Bob liegt. Es gibt für Bob keine Möglichkeit zu glauben, dass Mallory Alice ist, und Mallory Daten zur Verfügung zu stellen, die zwischen Alice und Bob vertraulich behandelt werden sollten.
Folglich kann Mallory diese Technik nur zum Lesen öffentlicher Daten verwenden.
Beachten Sie jedoch, dass das Entnehmen von Inhalten von der Website einer anderen Person und deren Anzeige auf eigene Faust eine Verletzung des Urheberrechts darstellen und Sie für rechtliche Schritte öffnen kann.
Etwas anderes als eine Web-App schreiben
Wie im Abschnitt "Warum die gleiche Ursprungsrichtlinie nur für JavaScript auf einer Webseite gilt" erwähnt, können Sie die SOP vermeiden, indem Sie kein JavaScript auf einer Webseite schreiben.
Das bedeutet nicht, dass Sie JavaScript und HTML nicht weiter verwenden können, aber Sie können es mithilfe eines anderen Mechanismus wie Node-WebKit oder PhoneGap verteilen.
Browser-Erweiterungen
Es ist möglich, dass eine Browsererweiterung die CORS-Header in die Antwort einfügt, bevor die Richtlinie für denselben Ursprung angewendet wird.
Diese können für die Entwicklung nützlich sein, sind jedoch für eine Produktionssite nicht praktikabel (es ist unangemessen, jeden Benutzer Ihrer Site zu bitten, eine Browsererweiterung zu installieren, die eine Sicherheitsfunktion seines Browsers deaktiviert).
Sie funktionieren auch in der Regel nur mit einfachen Anforderungen (Fehler bei der Bearbeitung von Preflight-OPTIONS-Anforderungen).
Eine richtige Entwicklungsumgebung mit einem lokalen Entwicklungs Mit Server
ist in der Regel ein besserer Ansatz.
Sonstige Sicherheitsrisiken
Beachten Sie, dass SOP / CORS keine XSS- , CSRF- oder SQL Injection- Angriffe abschwächt , die unabhängig voneinander behandelt werden müssen.
Zusammenfassung
- In Ihrem clientseitigen Code können Sie nichts tun , was den CORS-Zugriff auf den Server eines anderen ermöglicht .
- Wenn Sie den Server steuern, wird folgende Anforderung gestellt: Fügen Sie CORS-Berechtigungen hinzu.
- Wenn Sie mit der Person, die es kontrolliert, befreundet sind: Lassen Sie sie CORS-Berechtigungen hinzufügen.
- Wenn es ein öffentlicher Dienst ist:
- Lesen Sie die API-Dokumentation, um zu erfahren, was sie über den Zugriff mit clientseitigem JavaScript sagen:
- Sie werden möglicherweise aufgefordert, bestimmte URLs zu verwenden
- Sie könnten JSONP unterstützen
- Sie unterstützen möglicherweise überhaupt keinen Cross-Origin-Zugriff über clientseitigen Code (dies kann aus Sicherheitsgründen eine bewusste Entscheidung sein, insbesondere wenn Sie bei jeder Anforderung einen personalisierten API-Schlüssel übergeben müssen).
- Stellen Sie sicher, dass Sie keine Preflight-Anfrage auslösen, die Sie nicht benötigen. Die API gewährt möglicherweise Berechtigungen für einfache Anforderungen, jedoch nicht für vorab geflogene Anforderungen.
- Wenn keine der oben genannten Bedingungen zutrifft: Lassen Sie den Browser stattdessen mit Ihrem Server kommunizieren, und lassen Sie dann die Daten vom anderen Server abrufen und weiterleiten. (Es gibt auch gehostete Dienste von Drittanbietern, die CORS-Header an öffentlich zugängliche Ressourcen anhängen, die Sie verwenden können.)