JSON Hijacking è ancora un problema nei browser moderni?


149

Sto usando Backbone.js e il server web Tornado. Il comportamento standard per la ricezione di dati di raccolta in Backbone è l'invio come array JSON.

D'altro canto, il comportamento standard di Tornado è di non consentire l'array JSON a causa della seguente vulnerabilità:

http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx

Uno correlato è: http://haacked.com/archive/2009/06/25/json-hijacking.aspx

Mi sembra più naturale non dover avvolgere il mio JSON in un oggetto quando si tratta davvero di un elenco di oggetti.

Non sono riuscito a riprodurre questi attacchi nei browser moderni (ovvero Chrome, Firefox, Safari e IE9 attuali). Allo stesso tempo, non sono stato in grado di confermare da nessuna parte che i browser moderni avevano affrontato questi problemi.

Per assicurarmi di non essere fuorviato né da eventuali scarse capacità di programmazione né da scarse capacità di googling:

Questi attacchi al dirottamento JSON sono ancora oggi un problema nei browser moderni?

(Nota: ci scusiamo per il possibile duplicato di: è possibile eseguire il "dirottamento JSON" sul browser moderno? Ma poiché la risposta accettata non sembra rispondere alla domanda, ho pensato che fosse il momento di chiedere di nuovo e ottenere alcune spiegazioni più chiare .)


usando eval? quindi possibile altrimenti No. Se nulla è stato alterato o cambiato nel modo in cui la spina dorsale analizza la risposta, allora dovresti essere al sicuro
Deeptechtons,

10
In generale, non dovresti mai avvicinarti alla sicurezza web con il presupposto che qualcuno userà un browser "moderno".
Luca,

7
@Luke - Vedi sotto il commento a Reid. Ottimo punto in generale, ma non sto ponendo una domanda di sicurezza generale. (I miei utenti saranno in grado di autenticarsi solo se stanno utilizzando un browser moderno in primo luogo.)
Rocketman

4
@Luke, a volte dobbiamo andare avanti e permetterci di svilupparci con modelli moderni (come REST in questo caso: ottenere dati è un'operazione GET e non dovrebbe essere qualcos'altro) senza proteggere dalle vecchie minacce se ora sembrano applicare solo ad un piccolo pubblico. Quindi questa domanda è davvero preziosa, per consentire a uno di valutare se può ignorare questa minaccia o meno per il suo caso di applicazione. Ad un certo punto, è probabile che gli utenti con software molto obsoleto abbiano altri tipi di minacce (malware) da cui non saremo in grado di proteggerli comunque.
Frédéric,

2
@jpaugh, dove vedi questi presupposti? Suppongo solo in qualche modo che quelle persone con un software così obsoleto siano comunque "impraticabili". (Per giustificare il costo dei miei pattini, ero già abituato a mettere un terzo del loro prezzo in pattini da velocità in carbonio che erano consumati in meno di un terzo il tempo che mi ci vuole per sfinire i miei pattini attuali. E comunque, penso che ne valga la pena, a patto che ti piaccia cavalcare, che è il mio caso.)
Frédéric

Risposte:


112

No, non è più possibile acquisire valori passati ai costruttori []o {}in Firefox 21, Chrome 27 o IE 10. Ecco una piccola pagina di test, basata sui principali attacchi descritti in http://www.thespanner.co.uk / 2011/05/30 / json-hijacking / :

( http://jsfiddle.net/ph3Uv/2/ )

var capture = function() {
    var ta = document.querySelector('textarea')
	ta.innerHTML = '';
	ta.appendChild(document.createTextNode("Captured: "+JSON.stringify(arguments)));
	return arguments;
}
var original = Array;

var toggle = document.body.querySelector('input[type="checkbox"]');
var toggleCapture = function() {
    var isOn = toggle.checked;
    window.Array = isOn ? capture : original;
    if (isOn) {
        Object.defineProperty(Object.prototype, 'foo', {set: capture});    
    } else {
        delete Object.prototype.foo;
    }
};
toggle.addEventListener('click', toggleCapture);
toggleCapture();

[].forEach.call(document.body.querySelectorAll('input[type="button"]'), function(el) {
    el.addEventListener('click', function() {
        document.querySelector('textarea').innerHTML = 'Safe.';
        eval(this.value);
    });
});
<div><label><input type="checkbox" checked="checked"> Capture</label></div>
<div><input type="button" value="[1, 2]" /> <input type="button" value="Array(1, 2);" /> <input type="button" value="{foo: 'bar'}" /> <input type="button" value="({}).foo = 'bar';" /></div>
<div><textarea></textarea></div>

Sovrascrive window.Arraye aggiunge un setter Object.prototype.fooe verifica l'inizializzazione di matrici e oggetti tramite le forme corte e lunghe.

Le specifiche ES4 , nella sezione 1.5, "richiedono che le associazioni globali e standard di Object e Array siano utilizzate per costruire nuovi oggetti per gli inizializzatori di oggetti e array" e le note in Precedenti di implementazione che "Internet Explorer 6, Opera 9.20 e Safari 3 fanno non rispettare né i rebindings locali o globali di Object e Array, ma utilizzare i costruttori di Object e Array originali. " Questo è conservato in ES5, sezione 11.1.4 .

Allen Wirfs-Brock ha spiegato che ES5 specifica anche che l'inizializzazione dell'oggetto non deve attivare i setter, poiché utilizza DefineOwnProperty. MDN: Lavorando con Oggetti si nota che "A partire da JavaScript 1.8.1, i setter non vengono più chiamati quando si impostano le proprietà negli inizializzatori di oggetti e array." Questo problema è stato risolto nel numero V5 1015 .


28
Nel 2009 Brendan Eich ha suggerito che i browser non valutano gli script serviti da application / json ( bugzilla.mozilla.org/show_bug.cgi?id=376957#c75 ), che mi sembra comunque una buona idea.

2
Si noti che POST CSRF cieco è ancora possibile utilizzando i moduli, in particolare con la codifica text / plain, e deve essere sconfitto utilizzando token / nonces.

1
Sì al CSRF POST. Grazie per tutte le tue fantastiche informazioni qui.
Rocketman,

5
La tua affermazione è corretta quando si riferisce alla semplice sovrascrittura del costruttore di array. Tuttavia, Microsofts IE e Edge sono ancora vulnerabili al dirottamento JSON UTF-7. L'ho testato di recente (e per divertimento di nuovo oggi), e funziona ancora.
user857990

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.