Ist JSON-Hijacking in modernen Browsern immer noch ein Problem?

149

Ich verwende Backbone.js und den Tornado-Webserver. Das Standardverhalten für den Empfang von Erfassungsdaten in Backbone ist das Senden als JSON-Array.

Andererseits besteht das Standardverhalten von Tornado darin, JSON-Arrays aufgrund der folgenden Sicherheitsanfälligkeit nicht zuzulassen:

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

Ein verwandter ist: http://haacked.com/archive/2009/06/25/json-hijacking.aspx

Es fühlt sich für mich natürlicher an, meinen JSON nicht in ein Objekt einwickeln zu müssen, wenn es sich wirklich um eine Liste von Objekten handelt.

Ich konnte diese Angriffe in modernen Browsern (z. B. Chrome, Firefox, Safari und IE9) nicht reproduzieren. Gleichzeitig konnte ich nirgendwo bestätigen, dass moderne Browser diese Probleme behoben hatten.

Um sicherzustellen, dass ich weder durch mögliche schlechte Programmierkenntnisse noch durch schlechte Googeln-Fähigkeiten irregeführt werde:

Sind diese JSON-Hijacking-Angriffe in modernen Browsern noch heute ein Problem?

(Hinweis: Entschuldigen Sie das mögliche Duplikat zu: Ist es möglich, "JSON-Hijacking" in einem modernen Browser durchzuführen? Da die akzeptierte Antwort die Frage jedoch nicht zu beantworten scheint, dachte ich, es sei Zeit, sie erneut zu stellen und klarere Erklärungen zu erhalten .)

Raketenmann
quelle
mit eval? dann möglich sonst Nein. Wenn nichts geändert oder in der Art und Weise geändert wurde, wie das Backbone die Antwort analysiert, sollten Sie in Sicherheit sein
Deeptechtons
10
Im Allgemeinen sollten Sie sich niemals der Websicherheit mit der Annahme nähern, dass jemand einen "modernen" Browser verwenden wird.
Lukas
7
@ Luke - Siehe unten Kommentar zu Reid. Toller Punkt im Allgemeinen - aber ich stelle keine allgemeine Sicherheitsfrage. (Meine Benutzer können sich nur authentifizieren, wenn sie überhaupt einen modernen Browser verwenden.)
Rocketman
4
@Luke, manchmal müssen wir weitermachen und uns erlauben, uns mit modernen Mustern zu entwickeln (wie in diesem Fall REST: Das Abrufen von Daten ist eine GET-Operation und sollte nichts anderes sein), ohne uns vor alten Bedrohungen zu schützen, wenn sie jetzt nur noch zutreffen zu einem kleinen Publikum. Diese Frage ist also wirklich wertvoll, damit man beurteilen kann, ob er diese Bedrohung für seinen Anwendungsfall ignorieren kann oder nicht. Irgendwann haben Benutzer mit sehr veralteter Software sehr wahrscheinlich andere Arten von Bedrohungen (Malware), vor denen wir sie ohnehin nicht schützen können.
Frédéric
2
@jpaugh, wo sehen Sie solche Annahmen? Ich gehe nur ein wenig davon aus, dass diese Leute mit solch veralteter Software sowieso "ungeschützt" sind. (Um die Kosten für meine Skates zu rechtfertigen, war ich bereits daran gewöhnt, ein Drittel ihres Preises in Carbon-Speed-Skates zu stecken, die in weniger als einem Drittel der Zeit abgenutzt waren, in der ich meine aktuellen Skates abgenutzt habe Ich denke, sie sind es wert, vorausgesetzt, Sie reiten sie gern, was mein Fall ist.)
Frédéric

Antworten:

112

Nein, es ist nicht mehr möglich, Werte zu erfassen, die in Firefox 21, Chrome 27 oder IE 10 an die []oder {}Konstruktoren übergeben wurden. Hier ist eine kleine Testseite, die auf den unter http://www.thespanner.co.uk beschriebenen Hauptangriffen basiert / 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>

Es überschreibt window.Arrayund fügt einen Setter hinzu Object.prototype.foound testet die Initialisierung von Arrays und Objekten über die kurzen und langen Formulare.

Die ES4-Spezifikation in Abschnitt 1.5 "erfordert, dass die globalen Standardbindungen von Object und Array verwendet werden, um neue Objekte für Objekt- und Array-Initialisierer zu erstellen" und stellt in Implementation Precedent fest, dass "Internet Explorer 6, Opera 9.20 und Safari 3 dies tun Beachten Sie weder lokale noch globale Neubindungen von Object und Array, sondern verwenden Sie die ursprünglichen Object- und Array-Konstruktoren. " Dies wird in ES5, Abschnitt 11.1.4 beibehalten .

Allen Wirfs-Brock erklärte, dass ES5 auch angibt, dass die Objektinitialisierung keine Setter auslösen soll, da DefineOwnProperty verwendet wird. MDN: Arbeiten mit Objekten stellt fest, dass "Ab JavaScript 1.8.1 werden Setter nicht mehr aufgerufen, wenn Eigenschaften in Objekt- und Array-Initialisierern festgelegt werden." Dies wurde in V8-Ausgabe 1015 behoben .

jpaugh
quelle
28
Bereits 2009 schlug Brendan Eich vor, dass Browser keine als application / json dienenden Skripte auswerten ( bugzilla.mozilla.org/show_bug.cgi?id=376957#c75 ), was mir immer noch eine gute Idee erscheint.
2
Beachten Sie, dass blindes POST-CSRF mithilfe von Formularen weiterhin möglich ist, insbesondere mit der Text- / Nur-Codierung, und mithilfe von Token / Nonces besiegt werden muss.
1
Ja zum POST CSRF. Vielen Dank für all Ihre tollen Infos hier.
Rocketman
5
Ihre Aussage ist richtig, wenn sie sich nur auf das einfache Überschreiben des Array-Konstruktors bezieht. Microsoft IE und Edge sind jedoch weiterhin anfällig für das UTF-7-JSON-Hijacking. Habe es kürzlich getestet (und heute wieder zum Spaß) und es funktioniert immer noch.
user857990
2
UTF-16BE auch dank Gareth Heyes, blog.portswigger.net/2016/11/json-hijacking-for-modern-web.html
Aal GhEEz