Same-Origin-Policy
Die Same-Origin-Policy ist ein kritischer Sicherheitsmechanismus, der einschränkt, wie ein Dokument oder Skript von einem Origin auf eine Ressource aus einem anderen Origin zugreifen 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 (in den der Benutzer eingeloggt ist) oder einem Firmenintranet (das durch das Fehlen einer öffentlichen IP-Adresse vor direktem Zugriff durch den Angreifer geschützt ist) zu lesen und diese Daten an den Angreifer weiterzuleiten.
Definition eines Origins
Zwei URLs haben denselben Origin, wenn das Protokoll, der Port (falls angegeben) und der Host für beide gleich sind. Dies kann als "Scheme/Host/Port-Tupel" oder einfach "Tupel" bezeichnet werden. (Ein "Tupel" ist eine Menge von Elementen, die zusammen ein Ganzes bilden - eine generische Form für Doppel-/Dreifach-/Vierfach-/Fünffach/etc.)
Die folgende Tabelle zeigt 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 |
Gleiches Origin | Nur der Pfad unterscheidet sich |
http://store.company.com/dir/inner/another.html |
Gleiches Origin | Nur der Pfad unterscheidet sich |
https://store.company.com/page.html |
Fehler | Unterschiedliches Protokoll |
http://store.company.com:81/dir/page.html |
Fehler | Unterschiedlicher Port (http:// ist Port 80 standardmäßig) |
http://news.company.com/dir/page.html |
Fehler | Unterschiedlicher Host |
Geerbte Origins
Skripte, die von Seiten mit einer about:blank
oder einer 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.
Beispielsweise wird about:blank
oft als URL für neue, leere Popup-Fenster verwendet, in die das übergeordnete Skript Inhalte schreibt (z.B. über den Mechanismus Window.open()
). Wenn dieses Popup ebenfalls JavaScript enthält, würde dieses Skript denselben Origin erben wie das Skript, das es erstellt hat.
data:
URLs erhalten einen neuen, leeren Sicherheitskontext.
Datei-Origins
Moderne Browser behandeln den Origin von Dateien, die mit dem file:///
Schema geladen werden, normalerweise als undurchsichtige Origins.
Das bedeutet, dass, wenn eine Datei andere Dateien aus demselben Ordner (z.B.) einbindet, sie nicht davon ausgehen, dass sie vom selben Origin stammen, und möglicherweise CORS-Fehler verursachen.
Beachten Sie, dass die URL-Spezifikation besagt, dass der Origin von Dateien implementationsabhängig ist, und einige Browser können Dateien im gleichen Verzeichnis oder Unterverzeichnis als gleiches Origin behandeln, obwohl dies Sicherheitsimplikationen hat.
Änderung des Origin
Warnung:
Der hier beschriebene Ansatz (die Verwendung des document.domain
Setters) ist veraltet, da er die durch die Same-Origin-Policy gebotenen Sicherheitsvorkehrungen untergräbt und das Origin-Modell in Browsern kompliziert, was zu Interoperabilitätsproblemen und Sicherheitsfehlern führt.
Eine Seite kann ihren eigenen Origin ändern, mit einigen Einschränkungen. Ein Skript kann den Wert von document.domain
auf seine aktuelle Domain oder eine Superdomain seiner aktuellen Domain setzen. Wenn auf eine Superdomain der aktuellen Domain gesetzt, wird die kürzere Superdomain für Same-Origin-Prüfungen verwendet.
Zum Beispiel, wenn ein Skript aus dem Dokument bei http://store.company.com/dir/other.html
das Folgende ausführt:
document.domain = "company.com";
Danach kann die Seite den Same-Origin-Check mit http://company.com/dir/page.html
passieren (vorausgesetzt, dass http://company.com/dir/page.html
sein document.domain
auf "company.com"
setzt, um anzuzeigen, dass es dies erlauben möchte - siehe document.domain
für mehr). company.com
könnte jedoch nicht document.domain
auf othercompany.com
setzen, da dies keine Superdomain von company.com
ist.
Die Portnummer wird vom Browser separat geprüft. Jeder Aufruf von document.domain
, einschließlich document.domain = document.domain
, bewirkt, dass die Portnummer mit null
überschrieben wird. Daher kann man nicht company.com:8080
dazu bringen, mit company.com
zu kommunizieren, indem man nur document.domain = "company.com"
im ersten setzt. Es muss in beiden gesetzt werden, damit ihre Portnummern beide null
sind.
Der Mechanismus hat einige Einschränkungen. Zum Beispiel wird er ein SecurityError
DOMException
auslösen, wenn die document-domain
Permissions-Policy
aktiviert ist oder das Dokument in einem sandkastenartigen <iframe>
ist, und das Ändern des Origin auf diese Weise beeinflusst nicht die Originschecks, die von vielen Web-APIs verwendet werden (z.B. localStorage
, indexedDB
, BroadcastChannel
, SharedWorker
). Eine umfassendere Liste von Fehlermöglichkeiten finden Sie in Document.domain > Failures.
Hinweis:
Wenn Sie document.domain
verwenden, um einem Subdomain den Zugriff auf sein übergeordnetes Domain zu ermöglichen, müssen Sie document.domain
auf denselben Wert sowohl in der übergeordneten Domain als auch in der Subdomain setzen. Dies ist notwendig, selbst wenn Sie damit die übergeordnete Domain auf ihren ursprünglichen Wert zurücksetzen. Das Versäumnis, dies zu tun, kann zu Berechtigungsfehlern führen.
Netzwerkzugang zwischen verschiedenen Origins
Die Same-Origin-Policy steuert die Interaktionen zwischen zwei verschiedenen Origins, wie zum Beispiel wenn Sie fetch()
oder ein <img>
-Element verwenden. Diese Interaktionen werden typischerweise in drei Kategorien eingeordnet:
- Cross-Origin-Schreibvorgänge sind normalerweise erlaubt. Beispiele sind Links, Umleitungen und Formularübermittlungen. Einige HTTP-Anfragen erfordern Preflight.
- Cross-Origin-Einbettungen sind normalerweise erlaubt. (Beispiele sind unten aufgelistet.)
- Cross-Origin-Lesezugriffe sind typischerweise nicht erlaubt, aber Lesezugriff wird oft durch Einbettung geleakt. 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 von Ressourcen, die Cross-Origin eingebettet werden können:
- JavaScript mit
<script src="…"></script>
. Fehlermeldungen für Syntaxfehler sind nur für Skripte desselben Origins 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-Ladungen, wenn es eine Cross-Origin-Ladung ist, bei der der MIME-Typ falsch ist und die Ressource nicht mit einem gültigen CSS-Konstrukt beginnt. - Bilder, die durch
<img>
angezeigt werden. - Medien, die durch
<video>
und<audio>
abgespielt werden. - Externe Ressourcen, die mit
<object>
und<embed>
eingebettet werden. - Schriftarten, die mit
@font-face
angewendet werden. Einige Browser erlauben Cross-Origin-Schriftarten, andere erfordern dasselbe Origin. - Alles, was durch
<iframe>
eingebettet wird. Websites können denX-Frame-Options
-Header verwenden, um Cross-Origin-Framing zu verhindern.
Anleitung zum Aktivieren von Cross-Origin-Zugriff
Anleitung zum Blockieren von Cross-Origin-Zugriff
- Um Cross-Origin-Schreibvorgänge zu verhindern, überprüfen Sie ein schwer zu erratendes Token in der Anfrage - bekannt als Cross-Site Request Forgery (CSRF)-Token. Sie müssen Cross-Origin-Lesungen von Seiten verhindern, die dieses Token erfordern.
- Um Cross-Origin-Lesezugriffe auf eine Ressource zu verhindern, stellen Sie sicher, dass sie nicht eingebettet werden kann. Oft ist es notwendig, Einbettungen zu verhindern, da das Einbetten einer Ressource immer einige Informationen über sie leakt.
- Um Cross-Origin-Einbettungen zu verhindern, stellen Sie sicher, dass Ihre Ressource nicht als eine der oben aufgelisteten einbettbaren Formate interpretiert werden kann. Browser respektieren möglicherweise nicht den
Content-Type
-Header. Wenn Sie beispielsweise ein<script>
-Tag auf ein HTML-Dokument richten, 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 es Dokumenten, sich direkt aufeinander zu beziehen. Wenn zwei Dokumente nicht denselben Origin haben, bieten diese Referenzen nur sehr begrenzten Zugriff auf Window
und Location
-Objekte, wie in den nächsten beiden Abschnitten beschrieben.
Um zwischen Dokumenten von verschiedenen Origins zu kommunizieren, verwenden Sie window.postMessage
.
Spezifikation: HTML Living Standard § Cross-origin objects.
Window
Der folgende Cross-Origin-Zugriff auf Window
-Eigenschaften ist erlaubt:
Attribute | |
---|---|
window.closed |
Nur lesbar. |
window.frames |
Nur lesbar. |
window.length |
Nur lesbar. |
window.location |
Lesen/Schreiben. |
window.opener |
Nur lesbar. |
window.parent |
Nur lesbar. |
window.self |
Nur lesbar. |
window.top |
Nur lesbar. |
window.window |
Nur lesbar. |
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 schreibbar. |
Einige Browser erlauben den Zugriff auf mehr Eigenschaften als die oben genannten.
Zugriff auf Cross-Origin-Datenspeicherung
Der Zugriff auf im Browser gespeicherte Daten wie Web Storage 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 zugreifen 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 seine Verfügbarkeit mit den Flags Domain
, Path
, Secure
und HttpOnly
einschränken. Wenn Sie ein Cookie lesen, können Sie nicht sehen, von wo es gesetzt wurde. Selbst wenn Sie nur sichere HTTPS-Verbindungen verwenden, kann jedes Cookie, das Sie sehen, über eine unsichere Verbindung gesetzt worden sein.