2009-12-03 23 views
83

Benim Örümcek Sense gelen JSON ayrıştırmak için eval() kullanarak kötü bir fikir olduğunu bana uyarır. Ben sadece JSON.parse() - JavaScript'in bir parçası olduğunu varsayalım ve tarayıcıya özgü bir işlev olup olmadığını merak ediyorum - daha güvenli.JSON.parse vs eval()

cevap

97

Sen karşı daha hassas olduğu bu tür (satır içi belgelerinde here yılında daha fazla bilgi ve örnek) tarihsaat gibi bazı değerlere nasıl başa belirtmenize olanak sağlayan bir AIP parametre, Reviver kabul saldırılar kullanıyorsanız eval: JSON JavaScript bir alt kümesidir ve eval herkese açık ifadeleri JS kapıyı bırakacaktı oysa JSON.parse sadece JSON ayrıştırır.

+0

* "Saldırılara karşı daha savunmasızsınız" *, tamamen katılmıyorum! – Hydro

+2

Üzgünüm, Matheus, kabul etmeliyim. Sorun, “kullanıcı girişini” yorumlamak için eval() kullandığınız - bu, JavaScript'inizden başka bir kaynak olan (sunucunuzdan veya uyguladığınız diğer web hizmetlerinden gelen geri dönen değerler dahil) kaynaktır.Kullanıcıların kötü niyetli bir JavaScript'i doğrudan istemci uygulamanıza ya da sunucunun veritabanında depolanmış olan geçersiz kılınan veriler nedeniyle dolaylı olarak girmediğini ve daha sonra AJAX tarzı bir çağrı ile programınıza aktarıldığını garanti edemezsiniz. Hala "karışık yardımcısı" saldırıları önlemek için bireysel alanları doğrulamak gerekebilir, ancak JSON.parse kullanarak iyi bir ilk adımdır. – JackLThornton

+0

@Hydro Kavramın kısa kanıtı: 'eval (' alert (1) '); 'seçeneğini deneyin. –

4

JSON, yalnızca JavaScript'in bir alt kümesidir. Ancak eval, yalnızca JSON'un alt kümesini değil, yalnızca JavaScript dilini değerlendirir.

+0

Doğru, bunu biliyorum. JSON.parse() SADECE JSON'u değerlendirdiğini ve diğer tüm gelen verilerde başarısız olduğunu ima ediyor musunuz? Ya da sadece bir sarıcı: var myObject = eval ('(' + responseText + ')'); ?? –

+5

@Kevin Major: Evet, doğal olarak uygulanan JSON.parse (JavaScript motoruna doğrudan uygulanır) sadece JSON'u ayrıştırır. Ancak, diğer doğal olmayan uygulamaların kullanımı, bazı akıl sağlığı kontrollerini yapar ve daha sonra performans nedenlerinden ötürü “eval” kullanır. – Gumbo

9

JSON'u eval ile ayrıştırırsanız, ayrıştırılmakta olan dizenin kesinlikle herhangi bir şey içermesine izin verirsiniz, bu nedenle yalnızca bir veri kümesi olmak yerine, kendinize işlev çağrıları yürütme veya herhangi bir şey bulabilirsiniz. Ayrıca

JSON en parse Eğer

13

Tüm tarayıcılar böylece JSON dizeye eval() kullanmak gerekir kez olacak yerli JSON destek var. http://json.org'dan JSON ayrıştırıcısını kullanın, çünkü her şey sizin için daha kolay olur.

Eval() kötü ama bunu önlemek nerede bazı tarayıcılarda karşı onun gerekli bir kötülük ama Bunu yapmak !!!!!

29

Tüm JSON.parse uygulamaları büyük olasılıkla eval()

JSON.parseline 497 üzerinde yazıyor eval() kullanır Douglas Crockford's solution dayanmaktadır kullanın.

// 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 avantajı bağımsız değişken doğru JSON sözdizimi doğrular olmasıdır.

+50

Evet, bundan önceki satırın güvenli ve geçerli bir dizge olduğunu doğrulaması dışında. – nickf

+3

Linux Mint sistemimde Firefox 28 ve Chromium 33'te JSON.parse() işlevini test ettim. Firefox'taki eval() ile 2x, Chromium'da ise 4 kat daha hızlıydı. Hangi kaynak kodun yayınlandığından emin değilim, ancak tarayıcılarımda aynı şey değiller. – jbo5112

+0

@plodder "avantajı" muhtemelen bu doğrulamayı yapmak için ucuz değildir. – momomo

9

JSON.parse() ve eval() kabul edecek şeyler arasında bir fark yoktur. "{ShoppingCartName \ ": \" alisveris_sepeti: 2000 \

var x = \": "}" Bu konuda eval deneyin

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

bu example bakınız.

+1

eval, dizeleri kod deyimleri olarak ayrıştırdığından ve bu nedenle "{...}" değerini bir değer bildirimi ifadesi yerine kod ifadesi olarak gördüğü için çalışmaz. Eğer belirsizliği kaldırırsanız ("[{....}]" örneğin), ifadenin doğası hakkında bir şüphe yoktur ve değerlendirilen, ayrıştırılan nesne –

+1

Evet'i içeren bir dizi oluşturur. Geleneksel olarak, x parantez ile sarılır: eval ("(" + x + ")"). Söylediklerim hala geçerli: JSON.parse() kullanırken herhangi bir belirsizlik yok. –