評価は悪です…それで、代わりに何を使うべきですか?
-
22-07-2019 - |
質問
ajaxリクエストは、ユーザーの入力で満たされた標準のJSON配列を返します。入力はサニタイズされ、eval()関数を使用して、javascriptオブジェクトを簡単に作成し、ページを更新できます...
これが問題です。入力をサニタイズしようとしても、eval()関数は使用したくありません。 「評価なしでAJAXでJSONを使用する」方法については、Googleで確認しました。さまざまな方法で実行されました...
どちらを使用すべきですか?これを行うための標準で実績のある安全な方法はありますか?
解決
json.orgには javascriptライブラリ
があります単純な使用法:
JSON.parse('[{"some":"json"}]');
JSON.stringify([{some:'json'}]);
編集:コメントで指摘したように、ソースを見ると(最初にサニタイズされるように見えますが)evalを使用します
完全に回避するには、 json_parse または json-sans-eval
json2.jsは安全ではない、json_parse.jsは遅い、json-sans-eval.jsは検証されていない
他のヒント
これを行うための標準的な、実績のある安全な方法はありますか?
次のJavaScriptのECMAScript 3.1バージョンでは、これを行うための提案された標準的な方法があります。 JSON.parse 。
これは、IE8、Firefox 3.1 / 3.5、およびおそらく他の一般的なブラウザで将来サポートされる予定です。それまでの間、eval()にフォールバックするか、排他的に使用することができます。悪かもしれないし、そうでないかもしれない。確かにJSON.parseよりも遅くなります。しかし、これは今日のJSONを解析する通常の方法です。
攻撃者がJSONを介して吐き出しているコンテンツに悪意のあるJavaScriptを挿入できる場合、eval-is-evilよりも大きな問題が心配になります。
入力がサニタイズされたら、evalが最善の方法です。サーバーが危険にさらされた場合、人々はとにかくクライアントに必要なスクリプトを送信できます。そのため、評価を付けることは大きなセキュリティリスクではありません。クライアントに到達する前にパケットを操作する人が心配な場合は、スクリプト自体を変更できます。
evalについて心配する必要はありません。ただし、JSONが破損した場合にユーザーがJSエラーを受け取らないように、try ... catchブロックでラップしてください。
:)
JSONをJSオブジェクトに安全に変換するには、このライブラリ。
コマンドデザインパターンと比較する: http://en.wikipedia.org/wiki/Command_pattern 。これにより、クライアントが実行できる操作を正確に定義でき、アプリケーションは基礎となる解釈と同じくらい安全になります。
衛生設備で達成しようとしていることに依存します。 JSONと安全な評価に対するプロトタイプフレームワークのサポートで大成功を収めました。
注入のリスクがないと確信し、ループ内で eval()ing
をしていない場合は、 eval()
を使用します。確かに遅く、壊れる可能性があり、クライアントが追加のコードをダウンロードする必要がある他のオプションに比べて有利です。
"盗まれた" jQueryから
// Try to use the native JSON parser first
return window.JSON && window.JSON.parse ?
window.JSON.parse( data ) :
(new Function("return " + data))();
問題: evalが提起する問題は、グローバルスコープで実行されることです
eval.call(document, "console.log(this)")
eval.call(navigator, "console.log(this)")
eval.call(window, "console.log(this)")
(function(){eval.call(document, "console.log(this)")})()
>Window
シナリオ:
属性 onvisible
など、さまざまなドキュメント要素のマークアップコードで個々の属性を使用していると仮定します<img src="" onvisible="src='http://www.example.com/myimg.png';">
この属性を持つすべての要素を取得し、onvisible-content-stringをクロージャーに変えて、EventHandlerキューに入れたいと思います。これが、JS Functionコンストラクターの出番です。
Function === 0..constructor.constructor
>true
Function('return [this, arguments]').call(window, 1,2,3)
>Window, Arguments[3]]
Function('return [this, arguments]').call(document, 1,2,3)
>Document, Arguments[3]]
Function('return [this, arguments]').call(navigator, 1,2,3)
>Navigator, Arguments[3]]
すべてをまとめる:
var eventQueue = [];
var els = document.querySelectorAll('[onvisible]');
for (var el in els) {
var jscode = els[el].getAttribute('onvisible');
eventQueue.push( {el:els[el], cb:Function(jscode)} )
}
//eventQueue[0].cb.call(scope, args);