Same-Origin-Policy
Die Same-Origin-Policy ist ein kritischer Sicherheitsmechanismus, der einschränkt, wie ein Dokument oder Skript, das von einem Origin geladen wird, mit einer Ressource von einem anderen Origin interagieren kann.
Sie hilft, potenziell bösartige Dokumente zu isolieren und reduziert mögliche Angriffsvektoren. Zum Beispiel verhindert sie, dass eine bösartige Website im Internet JavaScript in einem Browser ausführt, um Daten von einem Drittanbieter-Webmail-Dienst (bei dem der Benutzer angemeldet ist) oder einem Unternehmensintranet (das durch fehlende öffentliche IP-Adresse vor direktem Zugriff durch den Angreifer geschützt ist) zu lesen und diese Daten an den Angreifer weiterzuleiten.
Definition eines Origin
Zwei URLs haben denselben Origin, wenn das Protokoll, der Port (falls angegeben) und der Host für beide gleich sind. Dies wird auch als "scheme/host/port tuple" oder einfach "tuple" bezeichnet. (Ein "Tuple" ist eine Menge von Elementen, die zusammen ein Ganzes bilden — eine generische Form für Doppel-/Dreifach-/Vierfach-/Fünfach/usw.)
Die folgende Tabelle gibt Beispiele für Origin-Vergleiche mit der URL http://store.company.com/dir/page.html
:
URL | Ergebnis | Grund |
---|---|---|
http://store.company.com/dir2/other.html |
Gleicher Origin | Nur der Pfad unterscheidet sich |
http://store.company.com/dir/inner/another.html |
Gleicher Origin | Nur der Pfad unterscheidet sich |
https://store.company.com/page.html |
Unterschiedlich | Unterschiedliches Protokoll |
http://store.company.com:81/dir/page.html |
Unterschiedlich | Unterschiedlicher Port (http:// ist standardmäßig Port 80) |
http://news.company.com/dir/page.html |
Unterschiedlich | Unterschiedlicher Host |
Geerbte Origins
Skripte, die von Seiten mit einem about:blank
oder javascript:
URL ausgeführt werden, erben den Origin des Dokuments, das diese URL enthält, da diese Arten von URLs keine Informationen über einen Origin-Server enthalten.
Zum Beispiel wird about:blank
häufig als URL neuer, leerer Popup-Fenster verwendet, in die das übergeordnete Skript Inhalt schreibt (z. B. über den Mechanismus Window.open()
). Wenn dieses Popup auch JavaScript enthält, würde dieses Skript denselben Origin erben wie das Skript, das es erstellt hat.
data:
URLs erhalten einen neuen, leeren Sicherheitskontext.
File Origins
Moderne Browser behandeln den Origin von Dateien, die mit dem file:///
Schema geladen werden, normalerweise als opake Origins. Dies bedeutet, dass, wenn eine Datei andere Dateien aus demselben Ordner einbezieht, sie nicht als vom selben Origin kommend angenommen werden und CORS Fehler auslösen können.
Beachten Sie, dass die URL-Spezifikation angibt, dass der Origin von Dateien implementationsabhängig ist und einige Browser Dateien im selben Verzeichnis oder Unterverzeichnis als gleichwertig behandeln können, obwohl dies Sicherheitsimplikationen hat.
Änderung des Origin
Warnung: Die hier beschriebene Methode (die Verwendung des Setzers document.domain
) ist veraltet, da sie die Sicherheitsvorkehrungen der Same-Origin-Policy untergräbt und das Origin-Modell in Browsern verkompliziert, was zu Interoperabilitätsproblemen und Sicherheitslücken führt.
Eine Seite kann ihren eigenen Origin ändern, jedoch mit einigen Einschränkungen. Ein Skript kann den Wert von document.domain
auf seinen aktuellen Domainnamen oder einen übergeordneten Domainnamen seiner aktuellen Domain setzen. Wenn es auf einen übergeordneten Domainnamen der aktuellen Domain gesetzt wird, wird der kürzere übergeordnete Domainname für Same-Origin-Prüfungen verwendet.
Angenommen, ein Skript im Dokument unter http://store.company.com/dir/other.html
führt Folgendes aus:
document.domain = "company.com";
Danach kann die Seite die Same-Origin-Prüfung mit http://company.com/dir/page.html
bestehen (vorausgesetzt, http://company.com/dir/page.html
setzt sein document.domain
auf "company.com"
, um anzuzeigen, dass es dies zulassen möchte - siehe document.domain
für mehr). company.com
könnte jedoch nicht document.domain
auf othercompany.com
setzen, da dies kein übergeordneter Domainname von company.com
ist.
Die Portnummer wird vom Browser separat geprüft. Jede Anweisung zu document.domain
, einschließlich document.domain = document.domain
, setzt die Portnummer auf null
. Daher kann man nicht company.com:8080
nur durch Setzen von document.domain = "company.com"
bei der ersten sprechen lassen. Es muss in beiden gesetzt werden, damit ihre Portnummern beide null
sind.
Der Mechanismus hat einige Einschränkungen. Zum Beispiel wird ein SecurityError
DOMException
ausgelöst, wenn die document-domain
Permissions-Policy
aktiviert ist oder das Dokument in einem sandboxed <iframe>
vorliegt, und die Änderung des Origins auf diese Weise beeinflusst nicht die Origin-Prüfungen, die von vielen Web-APIs verwendet werden (z. B. localStorage
, indexedDB
, BroadcastChannel
, SharedWorker
). Eine ausführlichere Liste der Fehlerfälle finden Sie in Document.domain > Failures.
Hinweis: Wenn Sie document.domain
verwenden, um einem Subdomain den Zugriff auf seine Eltern-Domain zu erlauben, müssen Sie document.domain
in beiden, der Eltern-Domain und der Subdomain, auf denselben Wert setzen. Dies ist notwendig, auch wenn Sie die Eltern-Domain damit auf ihren ursprünglichen Wert zurücksetzen. Tun Sie dies nicht, kann es zu Berechtigungsfehlern kommen.
Netzwerkzugriff über Origin-Grenzen hinweg
Die Same-Origin-Policy steuert Interaktionen zwischen zwei verschiedenen Origins, wie z. B. wenn Sie fetch()
oder ein <img>
-Element verwenden. Diese Interaktionen sind typischerweise in drei Kategorien unterteilt:
- Cross-Origin Schreibaktionen sind typischerweise erlaubt. Beispiele sind Links, Weiterleitungen und Formularübermittlungen. Einige HTTP-Anfragen erfordern Preflight.
- Cross-Origin Einbettungen sind typischerweise erlaubt. (Beispiele sind unten aufgeführt.)
- Cross-Origin Lesezugriffe sind typischerweise nicht erlaubt, aber Lesezugriff wird oft durch Einbettung offengelegt. Zum Beispiel können Sie die Abmessungen eines eingebetteten Bildes, die Aktionen eines eingebetteten Skripts oder die Verfügbarkeit einer eingebetteten Ressource lesen.
Hier sind einige Beispiele für Ressourcen, die Cross-Origin eingebettet werden können:
- JavaScript mit
<script src="…"></script>
. Fehlerdetails für Syntaxfehler sind nur für gleichwertige Skripte verfügbar. - CSS angewendet mit
<link rel="stylesheet" href="…">
. Aufgrund der entspannten Syntaxregeln von CSS erfordert Cross-Origin CSS einen korrektenContent-Type
Header. Browser blockieren Stylesheet-Ladevorgänge, wenn es sich um einen Cross-Origin-Ladevorgang handelt, bei dem der MIME-Typ falsch und die Ressource nicht mit einer gültigen CSS-Konstruktion beginnt. - Bilder, die durch
<img>
angezeigt werden. - Medien abgespielt durch
<video>
und<audio>
. - Externe Ressourcen eingebettet mit
<object>
und<embed>
. - Schriftarten, die mit
@font-face
angewendet werden. Einige Browser erlauben Cross-Origin-Schriftarten, andere erfordern den gleichen Origin. - Alles, was mit
<iframe>
eingebettet wird. Websites können denX-Frame-Options
Header verwenden, um das Cross-Origin-Framing zu verhindern.
So erlauben Sie die Cross-Origin-Zugriffe
So blockieren Sie die Cross-Origin-Zugriffe
- Um Cross-Origin-Schreibvorgänge zu verhindern, überprüfen Sie ein unerratbares Token in der Anfrage — bekannt als Cross-Site Request Forgery (CSRF) Token. Sie müssen Cross-Origin-Lesezugriffe von Seiten verhindern, die dieses Token erfordern.
- Um Cross-Origin-Lesezugriffe einer Ressource zu verhindern, stellen Sie sicher, dass diese nicht eingebettet werden kann. Es ist oft notwendig, die Einbettung zu verhindern, weil das Einbetten einer Ressource immer einige Informationen darüber offenlegt.
- Um Cross-Origin-Einbettungen zu verhindern, stellen Sie sicher, dass Ihre Ressource nicht als eines der oben aufgeführten einbettbaren Formate interpretiert werden kann. Browser respektieren möglicherweise nicht den
Content-Type
Header. Zum Beispiel, wenn Sie ein<script>
-Tag auf ein HTML-Dokument verweisen lassen, wird der Browser versuchen, das HTML als JavaScript zu parsen. Wenn Ihre Ressource kein Einstiegspunkt zu Ihrer Website ist, können Sie auch ein CSRF-Token verwenden, um die Einbettung zu verhindern.
Zugriff auf Cross-Origin-Skript-APIs
JavaScript-APIs wie iframe.contentWindow
, window.parent
, window.open
und window.opener
erlauben Dokumenten, sich gegenseitig direkt zu referenzieren. Wenn zwei Dokumente nicht den gleichen Origin haben, bieten diese Referenzen nur einen sehr eingeschränkten Zugriff auf Window
und Location
Objekte, wie in den nächsten zwei Abschnitten beschrieben.
Um zwischen Dokumenten aus verschiedenen Origins zu kommunizieren, verwenden Sie window.postMessage
.
Spezifikation: HTML Living Standard § Cross-origin objects.
Window
Der folgende Cross-Origin-Zugriff auf diese Window
-Eigenschaften ist erlaubt:
Attribute | |
---|---|
window.closed |
Nur lesen. |
window.frames |
Nur lesen. |
window.length |
Nur lesen. |
window.location |
Lesen/Schreiben. |
window.opener |
Nur lesen. |
window.parent |
Nur lesen. |
window.self |
Nur lesen. |
window.top |
Nur lesen. |
window.window |
Nur lesen. |
Einige Browser erlauben den Zugriff auf mehr Eigenschaften als die oben genannten.
Location
Der folgende Cross-Origin-Zugriff auf Location
-Eigenschaften ist erlaubt:
Methoden |
---|
location.replace |
Attribute | |
---|---|
location.href |
Nur schreiben. |
Einige Browser erlauben den Zugriff auf mehr Eigenschaften als die oben genannten.
Zugriff auf Datenspeicherung über Origin-Grenzen hinweg
Der Zugriff auf im Browser gespeicherte Daten wie Webspeicher und IndexedDB ist nach Origins getrennt. Jeder Origin erhält seinen eigenen separaten Speicher, und JavaScript in einem Origin kann nicht auf den Speicher eines anderen Origins lesen oder schreiben.
Cookies verwenden eine separate Definition von Origins. Eine Seite kann ein Cookie für ihre eigene Domain oder eine übergeordnete Domain setzen, solange die übergeordnete Domain kein öffentlicher Suffix ist. Firefox und Chrome verwenden die Public Suffix List, um zu bestimmen, ob eine Domain ein öffentlicher Suffix ist. Wenn Sie ein Cookie setzen, können Sie dessen Verfügbarkeit mit den Flags Domain
, Path
, Secure
und HttpOnly
einschränken. Wenn Sie ein Cookie lesen, können Sie nicht sehen, woher es gesetzt wurde. Selbst wenn Sie nur sichere https-Verbindungen verwenden, kann jedes von Ihnen gesehene Cookie über eine unsichere Verbindung gesetzt worden sein.