161

Backbone.js と Tornado Web サーバーを使用しています。バックボーンでコレクション データを受信するための標準的な動作は、JSON 配列として送信することです。

一方、Tornado の標準的な動作は、次の脆弱性のために JSON 配列を許可しないことです。

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

関連するものは次のとおりです。 http://haacked.com/archive/2009/06/25/json-hijacking.aspx

JSON が実際にはオブジェクトのリストである場合、JSON をオブジェクトにラップする必要がない方が自然だと感じます。

これらの攻撃を最新のブラウザー (現在の Chrome、Firefox、Safari、および IE9) で再現することはできませんでした。同時に、最新のブラウザーがこれらの問題に対処したことをどこにも確認できませんでした。

貧弱なプログラミングスキルや貧弱なグーグルスキルによって誤解されないようにするために:

これらの JSON ハイジャック攻撃は、現在のブラウザーでも依然として問題になっていますか?

(注: 重複の可能性について申し訳ありません: Is it possible to do 'JSON hijacking' on modern browser? しかし、受け入れられた回答は質問に答えていないようです - もう一度質問して、より明確な説明を得る時が来たと思いました.)

4

1 に答える 1

123

[]いいえ、Firefox 21、Chrome 27、または IE 10 では、またはコンストラクターに渡された値を取得することはできなくなりました。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>

window.Arrayこれは、setter をオーバーライドして追加Object.prototype.fooし、短い形式と長い形式で配列とオブジェクトの初期化をテストします。

ES4 仕様のセクション 1.5 では、「オブジェクトと配列のグローバルな標準バインディングを使用して、オブジェクトと配列の初期化子の新しいオブジェクトを構築する必要があります」と実装の前例に「Internet Explorer 6、Opera 9.20、および Safari 3 Object と Array のローカルまたはグローバルな再バインディングを考慮せず、元の Object および Array コンストラクターを使用します。" これはES5 のセクション 11.1.4 に保持されています。

Allen Wirfs-Brock 氏は、ES5 は、DefineOwnProperty を使用するため、オブジェクトの初期化がセッターをトリガーしないことも指定していると説明しました。MDN: Working with Objectsは、「JavaScript 1.8.1 から、オブジェクトおよび配列初期化子でプロパティを設定するときにセッターが呼び出されなくなりました」と述べています。これはV8 issue 1015で対処されました。

于 2013-06-02T05:54:24.103 に答える