2012-04-23 14 views
9
  1. Non vedo come la funzione di callback in JSONP sia diversa dalla funzione di callback di successo in AJAX.Non capisco come JSONP sia QUALSIASI diverso da AJAX

  2. Dato # 1, non vedo come sia fondamentalmente più sicuro.

  3. Quindi, l'unica differenza è un vincolo di dominio stesso artificiale con AJAX?

  4. Perché AJAX non può consentire solo richieste tra domini diversi; se questo può causare un buco di sicurezza, l'attacco non sarebbe solo XSS una richiesta JSONP?

Confuso, Max

risposta

17

una chiamata AJAX è una richiesta HTTP reale dal vostro cliente direttamente a un server. Le chiamate Ajax possono essere sincrone (il blocco fino al completamento) o asincrone. A causa delle protezioni di sicurezza di origine originaria, le chiamate ajax possono essere effettuate solo allo stesso server da cui proviene la pagina Web, a meno che il server di destinazione non consenta esplicitamente una richiesta di origine incrociata utilizzando CORS.

Le chiamate JSONP sono un'interessante modifica con il tag <script> che consente la comunicazione tra origini. In una chiamata JSONP, il client crea un tag script e inserisce un URL su di esso con un parametro di query callback=xxxx. Quella richiesta di script (tramite l'inserimento del tag script) viene inviata dal browser al server esterno. Il browser pensa semplicemente che stia richiedendo del codice javascript. Il server crea quindi un javascript speciale per gli scopi di questa chiamata e in quel javascript che verrà eseguito dal browser quando viene restituito, il server inserisce una chiamata di funzione alla funzione denominata nel parametro di query callback=xxxx. Definendo le variabili passando i dati a quella funzione, il server può comunicare i dati al client. Per JSONP, sia il client che il server devono collaborare su come funziona la chiamata JSONP e come vengono definiti i dati. Un client non può effettuare una chiamata JSONP a un server che non supporta esplicitamente JSONP poiché il tipo esatto giusto di risposta JSONP deve essere compilato dal server o non funzionerà.

Quindi, i due metodi di comunicazione funzionano in modo completamente diverso. Solo le chiamate Ajax possono essere sincrone. Per la natura dell'inserimento del tag <script>, le chiamate JSONP sono sempre asincrone.

In una chiamata Ajax, la risposta ritorna in un gestore di eventi Ajax.

In una chiamata JSONP, la risposta arriva quando il Javascript restituito chiama una funzione dell'utente.

In alcuni modi, JSONP è un buco di sicurezza che aggira il meccanismo di sicurezza di origine incrociata. Ma puoi chiamare solo server che scelgono esplicitamente di supportare un meccanismo simile a JSONP, quindi se un server non vuole che tu possa chiamarlo cross-origin, può impedirlo non supportando JSONP. Non è possibile effettuare chiamate ajax regolari a questi altri server.

I produttori di browser non possono davvero chiudere questa scappatoia perché se avessero fatto miliardi di pagine web avrebbero interrotto il fatto che già usassero JSONP o caricassero script da altri domini. Ad esempio, ogni pagina sul Web che utilizza jQuery al di fuori dei CDN di Google o Microsoft si interrompe perché al browser non è consentito scaricare javascript dai domini di origine incrociata.

JSONP è stato in gran parte inventato come work-around per essere in grado di effettuare richieste di origine incrociata.Tuttavia, poiché JSONP richiede il supporto esplicito del server per funzionare, non si è trattato di un problema di sicurezza in quanto una chiamata JSONP può essere effettuata solo su un server che ha deciso esplicitamente di consentire quel tipo di chiamata di origine incrociata. JSONP è usato molto meno ora di quanto non lo fosse perché CORS è stato inventato come un modo più elegante per controllarlo/permetterlo. CORS è l'acronimo di Cross Origin Resource Sharing e fornisce a un server di destinazione un mezzo per dire esattamente a un browser web quale tipo di richieste di origine incrociata sono consentite e persino per dirgli quali domini di pagine Web sono autorizzati a fare tali richieste. È disponibile un controllo molto più preciso di JSONP e tutti i browser moderni ora supportano CORS.

Ecco un esempio di come una chiamata tra origini causa problemi. Se è possibile caricare qualsiasi pagina Web arbitraria da qualsiasi altra pagina Web o effettuare qualsiasi chiamata arbitraria ajax, quindi immagina di aver già effettuato l'accesso all'interfaccia webmail su Yahoo in un'altra finestra del browser. Ciò significa che i tuoi cookie sono impostati per consentire alle richieste del tuo browser di recuperare i dati da Yahoo. Se il javascript in qualche altra pagina web era autorizzato a fare una richiesta webmail a Yahoo (che avrebbe automaticamente allegato i cookie), potrebbe quindi recuperare tutti i dati webmail e inviarli al proprio sito. Un sito Web potrebbe rimuovere tutti i dati registrati da qualsiasi altro sito web. Tutta la sicurezza Web sarebbe stata interrotta.

Ma, il modo in cui lo abbiamo oggi, finché Yahoo non supporta un'interfaccia JSONP che utilizza quegli stessi cookie web, è al sicuro da richieste JSONP non autorizzate.

Qui ci sono alcune altre buone writeups sui pericoli di cross-origine ajax e perché deve essere impedito:

Why the cross-domain Ajax is a security concern?

Why Cross-Domain AJAX call is not allowed?

Why are cross-domain AJAX requests labelled as a "security risk"?

+0

Grazie per la risposta. Ma ho alcune domande sulla tua risposta. Innanzitutto, quando dici "la chiamata ajax è una richiesta HTTP effettiva", stai implicando che JSONP non lo è? In secondo luogo, non vedo perché le risposte del server JSONP devono essere una chiamata di funzione, perché se può effettuare una chiamata di funzione, allora deve essere in grado di effettuare qualsiasi tipo di istruzione. In terzo luogo, ho sempre pensato che

1

La differenza fondamentale è che , per qualche ragione, è perfetto caricare i file javascript situati su altri domini (tramite tag script), ma per impostazione predefinita non è corretto caricare altre risorse del dominio incrociato.

Sono con voi, in quanto la delineazione sembra piuttosto arbitraria. In jQuery, quando si esegue una chiamata JSONP, si sta effettivamente creando un tag script, caricando la risorsa, quindi la libreria jQuery esegue lo script chiamando la funzione definita in tale risultato JSONP.

Ai miei occhi, non riesco a pensare a un ulteriore vettore di attacco introdotto consentendo il dominio incrociato AJAX che non è già ampio consentendo il caricamento di script cross domain, che è una pratica comune utilizzata ovunque (jQuery da googleCDN, script pubblicitari , google analytics e innumerevoli altri).

Da wikipedia

In addition, many legacy cross-domain operations predating JavaScript are not subjected to same-origin checks; one such example is the ability to include scripts across domains, or submit POST forms.

+0

Grazie per la risposta. Ma se questo è il caso, i browser non devono semplicemente rimuovere il vincolo dell'origine? Non ridurrebbe la sicurezza, ma può solo rendere lo sviluppo più facile e più coerente. – Max

+0

@Max e Nucleon - leggi gli ultimi due paragrafi della mia risposta (ho appena finito di aggiungerli) che descrive un grosso problema con le chiamate ajax incrociate. – jfriend00

+0

@ jfriend00 la risposta di bobnice su CSRF mi ha convinto. Grazie per aver pubblicato il link! – Max

2

callback di JSONP è non un callback reale. Piuttosto, JSONP funziona con script injection. Ad esempio, se si desidera effettuare una chiamata JSONP, si inserisce questo elemento di script nella DOM:

<script src="http://example.com/ajaxendpoint?jsonp=parseResponse"></script> 

La risposta del server sarà qualcosa di simile:

parseResponse({"json":"value"}); 

Sarà valutata in l'ambito globale della finestra.Quindi, in sostanza, JSONP è come un remoto exec(), dove viene consigliato al server quale stringa creare per l'esecuzione.

Questo è molto diverso da Ajax: con JSONP, la risposta è valutata in ambito globale dello script; con XMLHttpRequest, la risposta è ricevuta come una stringa e non valutata. (Inoltre, JSONP può essere utilizzato solo con GET, mentre AJAX consente qualsiasi metodo http.)

Così al tuo secondo numero, "Non vedo come sia fondamentalmente più sicuro". Bene, hai ragione, JSONP è in realtà estremamente insicuro. Il server può restituire qualsiasi script desiderato e fare tutto ciò che desidera sul tuo browser!

Le richieste tra domini non sono sicure perché possono essere utilizzate per rivelare informazioni sulla pagina corrente a una pagina su un altro dominio.

E hai ragione che qualsiasi attacco XSS può semplicemente utilizzare JSONP. Lo scopo di CORS non è quello di prevenire l'XSS (se hai script non affidabili in esecuzione sulla tua pagina, verrai comunque salvato).