JSON.parseとeval()


94

私のSpider Sense eval()は、着信JSONの解析にを使用することは悪い考えであることを警告しています。JSON.parse()ブラウザー固有の機能ではなくJavaScriptの一部であると私が思っているのは、もっと安全なのかと思っているところです。


パフォーマンスに関してJSON.parseeval、少なくともV8(ChromiumのJSエンジン)では、より高速です。ソース
ポール

回答:


110

を使用する場合、攻撃に対してより脆弱になりevalます。JSONはJavaScriptのサブセットであり、json.parseはJSONを解析するだけですが、evalすべてのJS式への扉を開いたままにします。


「あなたは攻撃に対してより脆弱です」、私は完全に同意しません!
Hydroper 2016年

4
すみません、マテウス、同意する必要があります。問題は、eval()を使用して「ユーザー入力」を解釈している場合です。これは、JavaScriptの外部の任意のソースです(サーブレットまたは呼び出した他のWebサービスからの戻り値を含む)。ユーザーが悪意のあるJavaScriptをクライアントアプリに直接入力したり、サーバーのデータベースに保存された未検証のデータが間接的にAJAXスタイルの呼び出しを介してプログラムに渡されたために間接的に入力したりしないことは保証できません。「混乱した代理」攻撃を回避するために個々のフィールドを検証する必要がある場合もありますが、JSON.parseを使用することは最初のステップとして適切です。
JackLThornton

1
@Hydroの概念実証:試してみてくださいeval('alert(1)');
Valerio Bozz

37

すべてのJSON.parse実装が使用する可能性が最も高いeval()

JSON.parseDouglas Crockfordのソリューションに基づいており、497行目で使用さeval()れています。

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

j = eval('(' + text + ')');

の利点JSON.parseは、引数が正しいJSON構文であることを検証することです。


56
そうです、その直前の行は、安全で有効な文字列であることを確認します。
nickf 2010

6
JSON.parse()Linux MintシステムのFirefox 28とChromium 33でテストしました。eval()Firefoxの2倍、Chromiumの4倍の速さでした。あなたが投稿しているソースコードはわかりませんが、私のブラウザーでは同じではありません。
jbo5112 14

@plodderの「アドバンテージ」は、その検証を行うのにおそらく安くはありません。
mmm 2015年

2
最新のブラウザーJSON.parse()eval()ベースのパーサーよりも安全で高速なネイティブ実装を提供します。
Mohammad Alhashash

15

すべてのブラウザーがネイティブJSONサポートを備えているわけではないeval() ため、JSON文字列を使用する必要がある場合があります。http://json.orgの JSONパーサーを使用してください。これにより、すべての処理がはるかに簡単になります。

Eval() 悪ですが、一部のブラウザでは必要な悪ですが、回避できる場合はそうしてください!!!!!!


12

JSON.parse()とeval()が受け入れるものには違いがあります。これについてevalを試してください:

var x = "{\" shoppingCartName \ ":\" shopping_cart:2000 \ "}"

eval(x)         //won't work
JSON.parse(x)   //does work

この例を参照してください。


1
evalは、文字列をコードステートメントとして解析し、 "{...}"を値宣言式ではなくコード式と見なすため、機能しません。あいまいさを取り除いた場合( "[{....}]"など)、式の性質に疑いはなく、evalは解析されたオブジェクトを含む配列を作成します
Charles HETIER

1
はい。従来、xは括弧で囲まれていました:eval( "(" + x + ")")。JSON.parse()を使用しても、あいまいさはありません。
Jeff Lowery 2014年

9

JSONを解析すると eval、解析される文字列に絶対に何でも含めることができるため、単なるデータセットではなく、関数呼び出しなどを実行することができます。

また、JSON parseは追加のパラメーターreviverを受け入れます。これにより、日時などの特定の値の処理方法を指定できます(詳細とインラインドキュメントの例はこちら)。


4

JSONはJavaScriptのサブセットにすぎません。ただしeval、JSONのサブセットだけでなく、完全なJavaScript言語を評価します。


そうだね。JSON.parse()がJSONのみを評価し、他のすべての受信データで失敗することを意味していますか?それとも単にラッパーですか:var myObject = eval( '(' + responseText + ')'); ??
ケビンメジャー

6
@Kevin Major:はい、ネイティブ実装JSON.parse(JavaScriptエンジンに直接実装)はJSONのみを解析します。しかし、他の非ネイティブ実装は、いくつかの健全性チェックevalを行ってから、パフォーマンス上の理由で使用します。
ガンボ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.