最近のブラウザでは、JSONハイジャックはまだ問題ですか?


149

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

一方、トルネードの標準的な動作は、次の脆弱性のために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をオブジェクトにラップする必要がないのは自然なことです。

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

プログラミングスキルの低下やグーグルスキルの低下の可能性によって誤解を招かないようにするには、次のようにします。

これらのJSONハイジャック攻撃は、今日のブラウザーでも依然として問題ですか?

(注:可能性のある重複して申し訳ありません:最近のブラウザで「JSONハイジャック」を実行することは可能ですか? しかし、受け入れられた回答が質問に回答していないようです-もう一度質問して、いくつかの明確な説明を取得するときがきたと思いました。)


evalを使用して?バックボーンが応答を解析する方法で何も変更または変更されていない場合、安全である必要があります
Deeptechtons

10
一般的に言って、誰かが「最新の」ブラウザを使用することを想定して、Webセキュリティに決してアプローチしないでください。
ルーク

7
@Luke-以下のReidへのコメントを参照してください。一般的に素晴らしい点ですが、一般的なセキュリティの質問はしていません。(私のユーザーが認証できるのは、そもそも最新のブラウザを使用している場合のみです。)
Rocketman

4
@Luke、先に進んで、最新のパターン(この場合はRESTなど)を使用して開発できるようにする必要があります(データの取得はGET操作であり、他のものではないはずです)。小さな聴衆に。したがって、この質問は本当に価値があり、アプリケーションのケースでこの脅威を無視できるかどうかを評価できるようになります。ある時点で、非常に古いソフトウェアを使用しているユーザーは、他の種類の脅威(マルウェア)を抱えている可能性が高く、そこから保護することはできません。
フレデリック

2
@jpaugh、そのような仮定はどこにありますか?とにかく、そのような時代遅れのソフトウェアを持っている人々はとにかく「保護できない」と思います。(私のスケート靴の費用の正当化については、私はすでに価格の3分の1を、現在のスケート靴を消耗させるのにかかる時間の3分の1未満で消耗したカーボンスピードスケート靴に入れることに慣れていました。そしてとにかく、あなたがそれらに乗るのが好きであるならば、彼らはそれが価値があると思います、それは私の場合です。)
フレデリック

回答:


112

いいえ、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してセッターを追加しObject.prototype.foo、テストします。

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

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


28
2009年にブレンダンアイヒは、ブラウザーがapplication / json(bugzilla.mozilla.org/show_bug.cgi?id=376957#c75)として機能するスクリプトを評価しないことを提案しましたが、それでも私には良い考えのようです。

2
ブラインドPOST CSRFは、フォーム、特にtext / plainエンコーディングを使用して引き続き可能であり、トークン/ノンスを使用して無効にする必要があることに注意してください。

1
はい、POST CSRFに対して。ここであなたの素晴らしい情報のすべてをありがとう。
ロケットマン2013年

5
Arrayコンストラクタの単純な上書きのみを参照している場合、ステートメントは正しいです。ただし、MicrosoftのIEとEdgeはまだUTF-7 JSONハイジャックに対して脆弱です。最近それをテストしました(そして今日も楽しみのために)、そしてそれはまだ動作します。
user857990 2016

2
UTF-16BEも、Gareth Heyesのおかげで、blog.portswigger.net / 2016/11 / json
eel ghEEz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.