web-dev-qa-db-fra.com

Façons de contourner la politique de même origine

La même politique d'origine

Je voulais créer un wiki communautaire sur HTML/JS règles de même origine pour aider, espérons-le, tous ceux qui recherchent ce sujet. C’est l’un des sujets les plus recherchés sur SO et il n’existe pas de wiki consolidé, alors je vais y aller :)

La même stratégie d'origine empêche un document ou un script chargé à partir d'une origine d'obtenir ou de définir les propriétés d'un document provenant d'une autre origine. Cette politique remonte à Netscape Navigator 2.0.

Quelles sont vos façons préférées de contourner les politiques de même origine?

S'il vous plaît, gardez les exemples commentés et liez de préférence vos sources.

150
David Titarenco

La méthode document.domain

  • Type de méthode: iframe .

Notez qu'il s'agit d'une méthode iframe qui définit la valeur de document.domain sur un suffixe du domaine actuel. Si tel est le cas, le domaine le plus court est utilisé pour les contrôles Origin ultérieurs. Par exemple, supposons qu'un script du document sous http://store.company.com/dir/other.html exécute l'instruction suivante:

document.domain = "company.com";

Une fois cette instruction exécutée, la page passera la vérification de l'origine avec http://company.com/dir/page.html. Toutefois, selon le même raisonnement, company.com ne pouvait pas définir document.domain sur othercompany.com.

Avec cette méthode, vous seriez autorisé à exécuter du javascript à partir d'un iframe provenant d'un sous-domaine d'une page provenant du domaine principal. Cette méthode ne convient pas aux ressources inter-domaines car des navigateurs tels que Firefox ne vous permettront pas de changer le document.domain en un domaine complètement étranger.

Source: https://developer.mozilla.org/en/Same_Origin_policy_for_JavaScript

La méthode de partage de ressources d'origine croisée

  • Type de méthode: AJAX.

Partage de ressources d'origine croisée (CORS) est un brouillon de travail du W3C qui définit la manière dont le navigateur et le serveur doivent communiquer pour accéder aux sources de différentes origines. L'idée de base de CORS est d'utiliser des en-têtes HTTP personnalisés pour permettre au navigateur et au serveur de se connaître suffisamment pour déterminer si la demande ou la réponse doit réussir ou échouer.

Pour une requête simple, utilisant GET ou POST sans en-tête personnalisé et dont le corps est text/plain, la demande est envoyée avec un en-tête supplémentaire appelé Origin. L'en-tête Origin contient l'origine (protocole, nom de domaine et port) de la page demandée afin que le serveur puisse facilement déterminer s'il doit ou non répondre à une réponse. Un exemple d'en-tête Origin pourrait ressembler à ceci:

Origin: http://www.stackoverflow.com

Si le serveur décide que la demande doit être autorisée, il envoie un en-tête Access-Control-Allow-Origin renvoyant la même origine que celle envoyée ou * s'il s'agit d'une ressource publique. Par exemple:

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

Si cet en-tête est manquant ou si les origines ne correspondent pas, le navigateur refuse la demande. Si tout va bien, le navigateur traite la demande. Notez que ni les demandes ni les réponses n'incluent d'informations de cookie.

L'équipe de Mozilla suggère dans leur article sur CORS que vous devriez vérifier l'existence de la propriété withCredentials pour déterminer si le navigateur prend en charge CORS via XHR. Vous pouvez ensuite coupler avec l'existence de l'objet XDomainRequest pour couvrir tous les navigateurs:

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();
}

Notez que pour que la méthode CORS fonctionne, vous devez avoir accès à tout type de mécanisme d'en-tête de serveur et ne pas accéder simplement à une ressource tierce.

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

La méthode window.postMessage

  • Type de méthode: iframe .

window.postMessage, lorsqu'il est appelé, provoque l'envoi d'une MessageEvent dans la fenêtre cible lorsqu'un script en attente à exécuter est terminé (par exemple, les gestionnaires d'événement restants si window.postMessage est appelé à partir d'un gestionnaire d'événement, les délais d’attente précédemment définis, etc.). La MessageEvent a le type de message, une propriété data qui est définie sur la valeur de chaîne du premier argument fourni à window.postMessage, une propriété Origin correspondant à l'origine du document principal dans la fenêtre appelant window.postMessage au moment où window.postMessage a été appelé, et une propriété source qui est la fenêtre à partir de laquelle window.postMessage est appelé.

Pour utiliser window.postMessage, un écouteur d'événement doit être associé:

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

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

Et une fonction receiveMessage doit être déclarée:

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

L'iframe hors site doit également envoyer les événements correctement via postMessage:

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

Toute fenêtre peut accéder à cette méthode sur n’importe quelle autre fenêtre, à tout moment, quel que soit l’emplacement du document dans la fenêtre, pour lui envoyer un message. Par conséquent, tout écouteur d'événements utilisé pour recevoir des messages doit d'abord vérifier l'identité de l'expéditeur du message, en utilisant les propriétés Origin et éventuellement source. Cela ne peut pas être sous-estimé: L'échec de la vérification des propriétés Origin et éventuellement source active les attaques de script entre sites.

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

84
David Titarenco

La méthode du proxy inverse

  • Type de méthode: Ajax

Configurer un simple proxy inverse sur le serveur permettra au navigateur d’utiliser des chemins relatifs pour les requêtes Ajax, alors que le serveur agirait comme un proxy vers n’importe quel emplacement distant.

Si vous utilisez mod_proxy dans Apache, la directive de configuration fondamentale pour configurer un proxy inverse est le ProxyPass. Il est généralement utilisé comme suit:

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

Dans ce cas, le navigateur pourrait demander /ajax/web_service.xml en tant qu'URL relative, mais le serveur le servirait en agissant en tant que proxy pour http://other-domain.com/ajax/web_service.xml.

Une caractéristique intéressante de cette méthode est que le proxy inverse peut facilement répartir les requêtes vers plusieurs serveurs principaux, agissant ainsi comme un équilibreur de charge .

41
Daniel Vassallo

J'utilise JSONP.

Fondamentalement, vous ajoutez

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

sur ta page.

some_func () devrait être appelé pour que vous soyez averti que les données sont dans.

17
Nicolas Viennot

AnyOrigin ne fonctionnait pas bien avec certains sites https, alors je viens d'écrire une alternative open source appelée quel que soit l'origine du projet qui semble bien fonctionner avec https.

Code sur github .

13
ripper234

Je ne peux pas prétendre au crédit de cette image, mais elle correspond à tout ce que je sais à ce sujet et offre un peu d'humour en même temps.

http://www.flickr.com/photos/iluvrhinestones/5889370258/

12
Mat Schaffer

Le moyen le plus récent de surmonter la politique de même origine que j'ai trouvée est http://anyorigin.com/

Le site est fait pour que vous lui donniez n'importe quelle URL et qu'il génère un code javascript/jquery qui vous permet d'obtenir le code HTML/les données, indépendamment de l'origine. En d'autres termes, toute URL ou page Web est une requête JSONP.

Je l'ai trouvé très utile :)

Voici un exemple de code javascript de anyorigin:

$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
    $('#output').html(data.contents);
});
12
rk1s

JSONP me vient à l’esprit:

JSONP ou "JSON avec remplissage" est un complément au format de données JSON de base, un modèle d'utilisation permettant à une page de demander et d'utiliser de manière plus significative JSON à partir d'un serveur autre que le serveur principal. JSONP est une alternative à une méthode plus récente appelée Partage de ressources d'origine croisée.

3
Sarfraz

Eh bien, j’ai utilisé curl dans PHP pour contourner cela. J'ai un service Web sur le 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;

?>

Voici le javascript qui appelle le fichier PHP

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();
}

Mon code HTML fonctionne sous WAMP dans le port 80. Nous y voilà, la même politique d'origine a été contournée :-)

1
harihb
1
Chris Cinelli

Personnellement, window.postMessage est le moyen le plus fiable que j'ai trouvé pour les navigateurs modernes. Vous devez faire un peu plus de travail pour vous assurer de ne pas vous laisser faire face aux attaques XSS, mais c'est un compromis raisonnable.

Il existe également plusieurs plugins pour les kits d’outils Javascript populaires qui encapsulent window.postMessage et fournissent des fonctionnalités similaires aux navigateurs plus anciens en utilisant les autres méthodes décrites ci-dessus.

1
Justin Niessner

Voici quelques solutions de contournement et explication de la même politique d'origine:
Thiru's Blog - Solution de contournement de la stratégie d'origine du navigateur

1
Thiru