Modi per aggirare la politica della stessa origine


150

La stessa politica di origine

Volevo creare una wiki della comunità relativa alle politiche HTML / JS della stessa origine per aiutare, spero, chiunque cerchi questo argomento. Questo è uno degli argomenti più cercati su SO e non esiste un wiki consolidato per questo, quindi eccomi qui :)

La stessa politica di origine impedisce a un documento o uno script caricato da un'origine di ottenere o impostare le proprietà di un documento da un'altra origine. Questa politica risale a Netscape Navigator 2.0.

Quali sono alcuni dei tuoi modi preferiti per aggirare le politiche sulla stessa origine?

Tieni gli esempi dettagliati e preferibilmente collega anche le tue fonti.


4
bella idea .. Dovresti mettere i tuoi esempi in risposte; così com'è, rendono la domanda piuttosto voluminosa
Shog9

1
È inoltre necessario aggiungere un elenco di implicazioni per la sicurezza per ciascun approccio. JSONP è altamente insicuro per i dati privati.
Erlend,

Perché la chiusura? Questa domanda (wiki) è stata abbastanza utile negli ultimi 2 anni. Inoltre, molte risposte sono supportate da riferimenti. Una spiegazione sarebbe apprezzata in quanto un not constructivetag sembra assolutamente insensato. Votato per la riapertura.
David Titarenco,

Risposte:


84

Il document.domainmetodo

  • Tipo di metodo: iframe .

Si noti che questo è un metodo iframe che imposta il valore di document.domain su un suffisso del dominio corrente. In tal caso, il dominio più breve viene utilizzato per i successivi controlli dell'origine. Ad esempio, supponiamo che uno script nel documento http://store.company.com/dir/other.htmlesegua la seguente istruzione:

document.domain = "company.com";

Dopo l'esecuzione dell'istruzione, la pagina passerà il controllo dell'origine con http://company.com/dir/page.html. Tuttavia, lo stesso ragionamento, company.com non poteva impostare document.domain a othercompany.com.

Con questo metodo, ti sarà permesso di estrarre javascript da un iframe proveniente da un sottodominio su una pagina proveniente dal dominio principale. Questo metodo non è adatto a risorse tra domini poiché browser come Firefox non ti permetteranno di passare document.domaina un dominio completamente estraneo.

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

Il metodo di condivisione delle risorse tra le origini

  • Tipo di metodo: AJAX .

Cross-Origin Resource Sharing (CORS) è una bozza di lavoro del W3C che definisce come il browser e il server devono comunicare quando accedono alle origini attraverso le origini. L'idea di base di CORS è quella di utilizzare le intestazioni HTTP personalizzate per consentire sia al browser che al server di conoscersi a vicenda per determinare se la richiesta o la risposta deve avere esito positivo o negativo.

Per una semplice richiesta, che utilizza una GETo POSTsenza intestazioni personalizzate e il cui corpo è text/plain, la richiesta viene inviata con un'intestazione aggiuntiva chiamata Origin. L'intestazione Origin contiene l'origine (protocollo, nome di dominio e porta) della pagina richiedente in modo che il server possa determinare facilmente se deve servire o meno una risposta. OriginUn'intestazione di esempio potrebbe apparire così:

Origin: http://www.stackoverflow.com

Se il server decide che la richiesta deve essere consentita, invia Access-Control-Allow-Originun'intestazione che riecheggia la stessa origine che è stata inviata o *se si tratta di una risorsa pubblica. Per esempio:

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

Se questa intestazione è mancante o le origini non corrispondono, il browser non accetta la richiesta. Se tutto va bene, il browser elabora la richiesta. Si noti che né le richieste né le risposte includono informazioni sui cookie.

Il team di Mozilla suggerisce nei loro post su CORS che è necessario verificare l'esistenza della withCredentials proprietà per determinare se il browser supporta CORS tramite XHR. È quindi possibile associare l'esistenza XDomainRequestdell'oggetto per coprire tutti i browser:

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

Nota per far funzionare il metodo CORS, devi avere accesso a qualsiasi tipo di meccanico dell'intestazione del server e non puoi semplicemente accedere a qualsiasi risorsa di terze parti.

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

Il window.postMessagemetodo

  • Tipo di metodo: iframe .

window.postMessage, quando viene chiamato, provoca la MessageEventspedizione di a nella finestra di destinazione al completamento di qualsiasi script in sospeso che deve essere eseguito (ad es. i gestori di eventi rimanenti se window.postMessagechiamati da un gestore di eventi, i timeout in sospeso impostati in precedenza, ecc.). Il MessageEventha il tipo di messaggio, una dataproprietà che è impostato al valore di stringa del primo argomento fornito window.postMessage, una originstruttura corrispondente all'origine del documento principale nella finestra chiamante window.postMessageal momento window.postMessageè stato chiamato, e una sourceproprietà che è la finestra da che window.postMessagesi chiama.

Per utilizzare window.postMessage, è necessario allegare un listener di eventi:

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

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

E una receiveMessagefunzione deve essere dichiarata:

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

L'iframe fuori sede deve anche inviare correttamente gli eventi tramite postMessage:

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

Qualsiasi finestra può accedere a questo metodo su qualsiasi altra finestra, in qualsiasi momento, indipendentemente dalla posizione del documento nella finestra, per inviargli un messaggio. Di conseguenza, qualsiasi listener di eventi utilizzato per ricevere messaggi deve prima verificare l'identità del mittente del messaggio, utilizzando l'origine e possibilmente le proprietà di origine. Questo non può essere sottovalutato: la mancata verifica delle proprietà origine possibilmente sourceabilita gli attacchi di scripting tra siti.

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



Spero di non essere troppo tardi per ottenere una risposta: l'unica domanda è: localhost è SEMPRE un'eccezione? non è sempre permesso? dovrei interrompere il test tramite il mio localhost?
Ayyash,

1
Non sono sicuro del perché, ma quando imposto: Access-Control-Allow-Origin: http://www.stackoverflow.com/anziché: Access-Control-Allow-Origin: http://www.stackoverflow.com(barra alla fine di url), non funziona in Safari e FF ma funziona in Chrome. Ovviamente senza barra funziona bene in tutti i browser.
mtfk,

1
Potrebbe valere la pena far sapere alle persone che il postMessagemetodo funziona solo per i browser che lo supportano, in quanto è un'aggiunta HTML5. Questo plugin cerca di renderlo conto. Ne ho parlato solo perché lo sto imparando nel modo più duro.
IronicMuffin

41

Il metodo del proxy inverso

  • Tipo di metodo: Ajax

L'impostazione di un semplice proxy inverso sul server consentirà al browser di utilizzare percorsi relativi per le richieste Ajax, mentre il server fungerebbe da proxy per qualsiasi posizione remota.

Se si utilizza mod_proxy in Apache, la direttiva di configurazione fondamentale per impostare un proxy inverso è la ProxyPass. In genere viene utilizzato come segue:

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

In questo caso, il browser sarebbe in grado di richiedere /ajax/web_service.xmlun URL relativo, ma il server lo servirebbe fungendo da proxy per http://other-domain.com/ajax/web_service.xml.

Una caratteristica interessante di questo metodo è che il proxy inverso può facilmente distribuire richieste verso più back-end, fungendo così da bilanciamento del carico .


17

Uso JSONP.

Fondamentalmente, aggiungi

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

sulla tua pagina.

some_func () dovrebbe essere chiamato in modo da essere avvisato che i dati sono in.


7
JSONP ha due problemi: a) Stai aggiungendo un tag script al dominio di destinazione. Possono inviare qualsiasi cosa indietro, anche javascript regolare (attacco XSS). Quindi devi davvero fidarti di loro per non fare cose cattive o essere hackerato b) Qualsiasi altra pagina web può aggiungere lo stesso tag-script e rubare i dati, quindi non usare mai JSONP per i dati privati.
Erlend,

1
@Erlend: qualsiasi informazione pubblicata sul web può essere recuperata da chiunque (a meno che non sia richiesta un'autenticazione adeguata). Il formato esatto di come vengono presentate queste informazioni non migliora o peggiora, anche se si tratta di JSONP.
T-Bull,

2
@ T-Bull: il problema è che un'autenticazione corretta è impossibile con JSONP. Un utente accede al sito A e quindi passa al sito B, che carica i dati da A utilizzando un tag di script JSONP. Come va bene. Quindi l'utente viene indotto a visitare il malvagio sito C, che utilizza anche un tag di script JSONP per caricare i dati da A. Quindi, poiché l'utente è autenticato con A, il proprietario di C ora può rubare i dati degli utenti da A. E questo anche se l'utente ha utilizzato l'autenticazione a due fattori per l'autenticazione con A. Il problema è che JSONP è altamente insicuro. E JSONP non è una presentazione. È un trasferimento di dati non sicuro.
Erlend,

1
JSONP supporta solo HTTP GET.
opyate

Quale file .js rappresenta questo -> "http: //..../someData.js.... Sto provando a leggere la dom da un altro sito lato client e devo aggirare la politica delle stesse origini .
CS_2013

13

AnyOrigin non ha funzionato bene con alcuni siti https, quindi ho appena scritto un'alternativa open source chiamata whateverorigin.org che sembra funzionare bene con https.

Codice su github .


@DavidTitarenco - mi ha fatto impazzire cercando di capire alcune cose che succedono nel ventre di qualunque origine. Fortunatamente ho trovato un post sul blog che mi ha aiutato, e ora il prossimo avrà un sito di test funzionante se mai ne avrà bisogno.
ripper234,

@neoascetic - risolto il problema ... l'URL deve essere codificato ora.
ripper234

12

Il modo più recente di superare la politica sulla stessa origine che ho trovato è http://anyorigin.com/

Il sito è stato creato in modo tale da dargli qualsiasi URL e genera codice javascript / jquery per te che ti consente di ottenere i dati / html, indipendentemente dalla sua origine. In altre parole, rende qualsiasi URL o pagina Web una richiesta JSONP.

L'ho trovato abbastanza utile :)

Ecco alcuni esempi di codice javascript di anyorigin:

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

Anche se mi ha dato alcuni problemi con https siti, in modo da controllare il mio alternativa open source di seguito: stackoverflow.com/questions/3076414/...
ripper234

13
Ciò significa che: a) anyorigin sarà in grado di leggere tutti i tuoi dati trasferiti tramite tem b) anyorigin può XSS il tuo sito, leggere tutti i tuoi dati sul tuo sito e consegnare malware ai tuoi utenti (cosa succede se anyorigin viene violato?)
Erlend,

@Erlend - fork Qualunque sia l'origine e ospitalo sul tuo server. Il codice è banale, quindi puoi esaminarlo per assicurarti che nessun exploit sia nascosto lì.
ripper234


3

Il JSONP viene in mente:

JSONP o "JSON con padding" è un complemento al formato di dati JSON di base, un modello di utilizzo che consente a una pagina di richiedere e utilizzare in modo più significativo JSON da un server diverso dal server primario. JSONP è un'alternativa a un metodo più recente chiamato Cross-Origin Resource Sharing.


Vedi il mio commento a JSONP sopra. Non è una buona scelta per i dati privati.
Erlend,

1

Personalmente, window.postMessageè il modo più affidabile che ho trovato per i browser moderni. Devi fare un po 'più di lavoro per assicurarti di non lasciarti aperto agli attacchi XSS, ma è un compromesso ragionevole.

Esistono anche diversi plug-in per i popolari toolkit Javascript che racchiudono window.postMessagefunzionalità simili a browser meno recenti utilizzando gli altri metodi discussi sopra.


1

Bene, ho usato l'arricciatura in PHP per aggirare questo. Ho un servizio web in esecuzione nella porta 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;

?>

Ecco il javascript che effettua la chiamata al file 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();
}

Il mio HTML funziona su WAMP nella porta 80. Quindi eccoci, la stessa politica di origine è stata elusa :-)



Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.