Möglichkeiten zur Umgehung der Politik des gleichen Ursprungs

150

Die gleiche Ursprungspolitik

Ich wollte ein Community-Wiki zu HTML / JS -Richtlinien gleichen Ursprungs erstellen, um hoffentlich allen zu helfen, die nach diesem Thema suchen. Dies ist eines der am meisten gesuchten Themen auf SO und es gibt kein konsolidiertes Wiki dafür, also los geht's :)

Dieselbe Ursprungsrichtlinie verhindert, dass ein von einem Ursprung geladenes Dokument oder Skript Eigenschaften eines Dokuments von einem anderen Ursprung abruft oder festlegt. Diese Richtlinie stammt aus Netscape Navigator 2.0.

Was sind einige Ihrer bevorzugten Methoden, um Richtlinien mit demselben Ursprung zu umgehen?

Bitte halten Sie Beispiele ausführlich und verknüpfen Sie vorzugsweise auch Ihre Quellen.

David Titarenco
quelle
4
nette Idee .. Sie sollten Ihre Beispiele in Antwort (en) setzen; so wie es
aussieht
1
Sie sollten auch eine Liste der Sicherheitsauswirkungen für jeden Ansatz hinzufügen. JSONP ist für private Daten sehr unsicher.
Erlend
Warum das Ende? Diese (Wiki) Frage war in den letzten 2 Jahren sehr nützlich. Außerdem sind viele Antworten werden durch Referenzen unterstützt. Eine Erklärung wäre wünschenswert, da ein not constructiveTag völlig verrückt erscheint. Für die Wiedereröffnung gestimmt.
David Titarenco

Antworten:

84

Die document.domainMethode

  • Methodentyp: iframe .

Beachten Sie, dass dies eine iframe-Methode ist, die den Wert von document.domain auf ein Suffix der aktuellen Domäne setzt. In diesem Fall wird die kürzere Domain für nachfolgende Ursprungsprüfungen verwendet. Angenommen, ein Skript im Dokument bei http://store.company.com/dir/other.htmlführt die folgende Anweisung aus:

document.domain = "company.com";

Nachdem diese Anweisung ausgeführt wurde, besteht die Seite die Ursprungsprüfung mit http://company.com/dir/page.html. Doch durch die gleiche Argumentation, company.com konnte nicht gesetzt document.domain zuothercompany.com .

Mit dieser Methode können Sie Javascript von einem Iframe ausführen, der in einer Subdomain auf einer Seite in der Hauptdomain gespeichert ist. Diese Methode eignet sich nicht für domänenübergreifende Ressourcen, da Sie in Browsern wie Firefox keine Änderungen vornehmen könnendocument.domain in eine völlig fremde Domain .

Quelle: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript

Die Methode zur gemeinsamen Nutzung von Ressourcen zwischen verschiedenen Ursprüngen

  • Methodentyp: AJAX .

Cross-Origin Resource Sharing (CORS) ist ein W3C-Arbeitsentwurf, der definiert, wie Browser und Server beim Zugriff auf Quellen über Ursprünge hinweg kommunizieren müssen. Die Grundidee von CORS besteht darin, benutzerdefinierte HTTP-Header zu verwenden, damit sowohl der Browser als auch der Server genug voneinander wissen, um festzustellen, ob die Anforderung oder Antwort erfolgreich sein oder fehlschlagen sollte.

Für eine einfache Anfrage, die entweder GEToder POSTohne benutzerdefinierte Header verwendet und deren Hauptteil ist text/plain, wird die Anfrage mit einem zusätzlichen Header namens aufgerufen Origin. Der Origin-Header enthält den Ursprung (Protokoll, Domänenname und Port) der anfordernden Seite, sodass der Server leicht bestimmen kann, ob eine Antwort bereitgestellt werden soll oder nicht. Ein Beispielheader Originkönnte folgendermaßen aussehen:

Origin: http://www.stackoverflow.com

Wenn der Server entscheidet, dass die Anforderung zulässig sein soll, sendet er einen Access-Control-Allow-OriginHeader, der denselben Ursprung wiedergibt, der gesendet wurde, oder *wenn es sich um eine öffentliche Ressource handelt. Beispielsweise:

Access-Control-Allow-Origin: http://www.stackoverflow.com

Wenn dieser Header fehlt oder die Ursprünge nicht übereinstimmen, lässt der Browser die Anforderung nicht zu. Wenn alles in Ordnung ist, verarbeitet der Browser die Anfrage. Beachten Sie, dass weder die Anfragen noch die Antworten Cookie-Informationen enthalten.

Das Mozilla-Team schlägt in seinem Beitrag zu CORS vor , das Vorhandensein der withCredentials Eigenschaft zu überprüfen, um festzustellen, ob der Browser CORS über XHR unterstützt. Sie können dann mit der Existenz des XDomainRequestObjekts koppeln , um alle Browser abzudecken:

function createCORSRequest(method, url){
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr){
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined"){
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}

var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
    request.onload = function() {
        // ...
    };
    request.onreadystatechange = handler;
    request.send();
}

Beachten Sie, dass Sie für die Funktion der CORS-Methode Zugriff auf alle Arten von Server-Header-Mechanismen haben müssen und nicht einfach auf Ressourcen von Drittanbietern zugreifen können.

Quelle: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/

Die window.postMessageMethode

  • Methodentyp: iframe .

window.postMessageWenn ein Aufruf ausgeführt wird, wird a MessageEventim Zielfenster ausgelöst, wenn ein ausstehendes Skript abgeschlossen ist, das ausgeführt werden muss (z. B. verbleibende Ereignishandler, wenn window.postMessagesie von einem Ereignishandler aufgerufen werden, zuvor festgelegte ausstehende Zeitüberschreitungen usw.). Das MessageEventhat die Typnachricht, eine dataEigenschaft, die auf den Zeichenfolgenwert des ersten bereitgestellten Arguments festgelegt ist window.postMessage, eine originEigenschaft, die dem Ursprung des Hauptdokuments in dem Fenster entspricht, window.postMessagedas zum Zeitpunkt des Aufrufs window.postMessageaufgerufen wurde, und eine sourceEigenschaft, aus der das Fenster stammt welches window.postMessageheißt.

Zur Verwendung window.postMessagemuss ein Ereignis-Listener angehängt sein:

    // Internet Explorer
    window.attachEvent('onmessage',receiveMessage);

    // Opera/Mozilla/Webkit
    window.addEventListener("message", receiveMessage, false);

Und eine receiveMessageFunktion muss deklariert werden:

function receiveMessage(event)
{
    // do something with event.data;
}

Der externe Iframe muss außerdem Ereignisse ordnungsgemäß senden über postMessage:

<script>window.parent.postMessage('foo','*')</script>

Jedes Fenster kann jederzeit auf diese Methode in jedem anderen Fenster zugreifen, unabhängig vom Speicherort des Dokuments im Fenster, um ihm eine Nachricht zu senden. Folglich muss jeder Ereignis-Listener, der zum Empfangen von Nachrichten verwendet wird, zuerst die Identität des Absenders der Nachricht unter Verwendung der Eigenschaften origin und möglicherweise source überprüfen. Dies kann nicht unterschätzt werden: Wenn die Eigenschaften und möglicherweise nicht überprüft werden, werden standortübergreifende Skriptangriffe aktiviert.originsource

Quelle: https://developer.mozilla.org/en/DOM/window.postMessage

David Titarenco
quelle
Ich hoffe, ich bin nicht zu spät, um eine Antwort zu bekommen: Ist nur die Frage, ist localhost IMMER eine Ausnahme? ist es immer nicht erlaubt sollte ich aufhören, über meinen lokalen Host zu testen?
Ayyash
1
Ich bin mir nicht sicher warum, aber wenn ich Folgendes einstelle: Access-Control-Allow-Origin: http://www.stackoverflow.com/anstelle von: Access-Control-Allow-Origin: http://www.stackoverflow.com(Schrägstrich am Ende der URL) funktioniert es nicht in Safari und FF, sondern in Chrome. Natürlich funktioniert ohne Schrägstrich in allen Browsern einwandfrei.
MTFK
1
Es könnte sich lohnen, die Leute wissen zu lassen, dass die postMessageMethode nur für Browser funktioniert, die sie unterstützen, da es sich um eine HTML5-Ergänzung handelt. Dieses Plugin versucht dies zu berücksichtigen. Ich erwähne es nur, weil ich das auf die harte Tour lerne.
IronicMuffin
41

Die Reverse-Proxy-Methode

  • Methodentyp: Ajax

Durch das Einrichten eines einfachen Reverse-Proxys auf dem Server kann der Browser relative Pfade für die Ajax-Anforderungen verwenden, während der Server als Proxy für einen beliebigen Remotestandort fungiert.

Wenn Sie mod_proxy in Apache verwenden, lautet die grundlegende Konfigurationsanweisung zum Einrichten eines Reverse-Proxys die ProxyPass. Es wird normalerweise wie folgt verwendet:

ProxyPass     /ajax/     http://other-domain.com/ajax/

In diesem Fall kann der Browser /ajax/web_service.xmleine relative URL anfordern , der Server fungiert jedoch als Proxy für http://other-domain.com/ajax/web_service.xml.

Ein interessantes Merkmal dieser Methode ist, dass der Reverse-Proxy Anforderungen problemlos auf mehrere Back-Ends verteilen kann und somit als Load Balancer fungiert .

Daniel Vassallo
quelle
17

Ich benutze JSONP.

Grundsätzlich fügen Sie hinzu

<script src="http://..../someData.js?callback=some_func"/>

Auf deiner Seite.

some_func () sollte aufgerufen werden, damit Sie benachrichtigt werden, dass sich die Daten in befinden.

Nicolas Viennot
quelle
7
JSONP hat zwei Probleme: a) Sie fügen der Zieldomäne ein Skript-Tag hinzu. Sie können alles zurückschicken, sogar reguläres Javascript (XSS-Angriff). Sie müssen ihnen also wirklich vertrauen, dass sie keine schlechten Dinge tun oder gehackt werden. B) Jede andere Webseite kann dasselbe Skript-Tag hinzufügen und die Daten stehlen. Verwenden Sie JSONP also niemals für private Daten.
Erlend
1
@Erlend: Alle im Web bereitgestellten Informationen können von jedem abgerufen werden (es sei denn, eine ordnungsgemäße Authentifizierung ist erforderlich). Das genaue Format der Darstellung dieser Informationen macht dies nicht besser oder schlechter, auch wenn es sich um JSONP handelt.
T-Bull
2
@ T-Bull: Das Problem ist, dass eine ordnungsgemäße Authentifizierung mit JSONP nicht möglich ist. Ein Benutzer meldet sich an Standort A an und wechselt dann zu Standort B, der Daten von A mithilfe eines JSONP-Skript-Tags lädt. Da ist gut und schön. Dann wird der Benutzer dazu verleitet, die böse Site C zu besuchen, die auch ein JSONP-Skript-Tag verwendet, um Daten von A zu laden. Da der Benutzer also mit A authentifiziert ist, kann der Eigentümer von C jetzt die Benutzerdaten von A stehlen. Und das ist auch dann der Fall Der Benutzer verwendete die Zwei-Faktor-Authentifizierung zur Authentifizierung mit A. Das Problem ist, dass JSONP sehr unsicher ist. Und JSONP ist keine Präsentation. Es ist eine unsichere Datenübertragung.
Erlend
1
JSONP unterstützt nur HTTP GET.
Opyate
Welche .js-Datei stellt dies dar -> "http: //..../someData.js....Ich versuche, den Dom von einer anderen Site-Client-Seite zu lesen, und muss die Richtlinie mit demselben Ursprung umgehen .
CS_2013
13

AnyOrigin funktionierte mit einigen https-Sites nicht gut, daher habe ich gerade eine Open-Source-Alternative namens Whateverorigin.org geschrieben , die mit https gut zu funktionieren scheint.

Code auf Github .

ripper234
quelle
@ DavidTitarenco - es hat mich verrückt gemacht, einige der Dinge zu verstehen, die im Bauch eines jeden Ureinwohners vor sich gehen. Zum Glück habe ich einen Blog-Beitrag gefunden, der geholfen hat, und jetzt wird der nächste eine funktionierende Testseite haben, falls er sie jemals braucht.
Ripper234
@neoascetic - die Verwendung wurde korrigiert ... die URL muss jetzt verschlüsselt werden.
Ripper234
12

Die jüngste Methode zur Überwindung der Richtlinie mit demselben Ursprung, die ich gefunden habe, ist http://anyorigin.com/.

Die Site wurde so erstellt, dass Sie ihr nur eine URL geben und Javascript / JQuery-Code für Sie generieren, mit dem Sie HTML / Daten unabhängig von ihrer Herkunft abrufen können. Mit anderen Worten, es macht jede URL oder Webseite zu einer JSONP-Anfrage.

Ich fand es ziemlich nützlich :)

Hier ist ein Beispiel für einen Javascript-Code von anyorigin:

$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
    $('#output').html(data.contents);
});
rk1s
quelle
Obwohl es mir einige Probleme mit https-Sites gab, sehen Sie sich meine Open-Source-Alternative unten an: stackoverflow.com/questions/3076414/…
ripper234
13
Dies bedeutet, dass: a) anyorigin alle Ihre über tem übertragenen Daten lesen kann b) anyorigin Ihre Site XSS-fähig machen, alle Ihre Daten auf Ihrer Site lesen und Ihren Benutzern Malware bereitstellen kann (was passiert, wenn anyorigin gehackt wird?)
Erlend
@Erlend - Fork Whateverorigin und hosten Sie es auf Ihrem eigenen Server. Der Code ist trivial, sodass Sie ihn überprüfen können, um sicherzustellen, dass dort keine Exploits versteckt sind.
Ripper234
3

Das JSONP fällt mir ein:

JSONP oder "JSON mit Auffüllung" ist eine Ergänzung zum Basis-JSON-Datenformat, einem Verwendungsmuster, mit dem eine Seite JSON von einem anderen Server als dem Primärserver anfordern und sinnvoller verwenden kann. JSONP ist eine Alternative zu einer neueren Methode namens Cross-Origin Resource Sharing.

Sarfraz
quelle
Siehe meinen Kommentar zu JSONP oben. Keine gute Wahl für private Daten.
Erlend
1

Persönlich window.postMessageist der zuverlässigste Weg, den ich für moderne Browser gefunden habe. Sie müssen ein wenig mehr arbeiten, um sicherzustellen, dass Sie sich nicht für XSS-Angriffe offen lassen, aber dies ist ein vernünftiger Kompromiss.

Es gibt auch mehrere Plugins für die beliebten Javascript-Toolkits window.postMessage, die ähnliche Funktionen wie ältere Browser mit den anderen oben beschriebenen Methoden bieten.

Justin Niessner
quelle
1

Nun, ich habe Curl in PHP verwendet, um dies zu umgehen. Ich habe einen Webservice in Port 82.

<?php

$curl = curl_init();
$timeout = 30;
$ret = "";
$url="http://localhost:82/put_val?val=".$_GET["val"];
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl, CURLOPT_MAXREDIRS, 20);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5");
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
$text = curl_exec($curl);
echo $text;

?>

Hier ist das Javascript, mit dem die PHP-Datei aufgerufen wird

function getdata(obj1, obj2) {

    var xmlhttp;

    if (window.XMLHttpRequest)
            xmlhttp=new XMLHttpRequest();
    else
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
                document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET","phpURLFile.php?eqp="+obj1+"&val="+obj2,true);
    xmlhttp.send();
}

Mein HTML läuft auf WAMP in Port 80. Also los geht's, die gleiche Ursprungsrichtlinie wurde umgangen :-)

harihb
quelle