Impedisce la divulgazione della risposta tramite il dirottamento JSON.
In teoria, il contenuto delle risposte HTTP è protetto dalla stessa politica di origine: le pagine di un dominio non possono ottenere alcuna informazione dalle pagine dell'altro dominio (se non esplicitamente consentito).
Un utente malintenzionato può richiedere pagine su altri domini per conto dell'utente, ad esempio utilizzando un tag <script src=...>
o <img>
, ma non può ottenere alcuna informazione sul risultato (intestazioni, contenuti).
Pertanto, se visiti la pagina di un utente malintenzionato, non è in grado di leggere la tua email da gmail.com.
Tranne il fatto che quando si utilizza un tag di script per richiedere il contenuto JSON, il JSON viene eseguito come Javascript nell'ambiente controllato di un utente malintenzionato. Se l'attaccante può sostituire il costruttore di array o oggetti o qualche altro metodo utilizzato durante la costruzione di oggetti, qualsiasi cosa nel JSON passerebbe attraverso il codice dell'attaccante e verrebbe divulgata.
Si noti che ciò accade nel momento in cui JSON viene eseguito come Javascript, non nel momento in cui viene analizzato.
Esistono diverse contromisure:
Assicurarsi che JSON non venga mai eseguito
Inserendo una while(1);
dichiarazione prima dei dati JSON, Google si assicura che i dati JSON non vengano mai eseguiti come Javascript.
Solo una pagina legittima può ottenere l'intero contenuto, eliminare il file while(1);
e analizzare il resto come JSON.
Cose come for(;;);
sono state viste su Facebook per esempio, con gli stessi risultati.
Assicurarsi che JSON non sia Javascript valido
Allo stesso modo, l'aggiunta di token non validi prima del JSON, come &&&START&&&
, assicura che non venga mai eseguito.
Restituisce sempre JSON con un oggetto all'esterno
Questo è il OWASP
modo consigliato per proteggere dal dirottamento JSON ed è quello meno invadente.
Simile alle precedenti contromisure, si assicura che JSON non venga mai eseguito come Javascript.
Un oggetto JSON valido, quando non è racchiuso tra nulla, non è valido in Javascript:
eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :
Questo è comunque valido JSON:
JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}
Quindi, assicurati di restituire sempre un oggetto al livello più alto della risposta assicurandoti che JSON non sia Javascript valido, pur essendo comunque JSON valido.
Come notato da @hvd nei commenti, l'oggetto vuoto {}
è Javascript valido e sapere che l'oggetto è vuoto può essere essa stessa un'informazione preziosa.
Confronto dei metodi sopra indicati
Il modo OWASP è meno invadente, in quanto non necessita di modifiche alla libreria client e trasferisce JSON valido. Non è sicuro, tuttavia, se i bug passati o futuri del browser potrebbero sconfiggere questo. Come notato da @oriadam, non è chiaro se i dati potrebbero essere trapelati in un errore di analisi attraverso una gestione degli errori o meno (ad esempio window.onerror).
Per Google è necessario che la libreria client supporti la deserializzazione automatica e può essere considerata più sicura riguardo ai bug del browser.
Entrambi i metodi richiedono modifiche sul lato server per evitare agli sviluppatori di inviare accidentalmente JSON vulnerabile.