JSON.parse बनाम eval ()


94

मेरा स्पाइडर सेंस मुझे चेतावनी देता है कि eval()आने वाले JSON को पार्स करने के लिए उपयोग करना एक बुरा विचार है। मैं बस सोच रहा था कि JSON.parse()- जो मुझे लगता है कि जावास्क्रिप्ट का एक हिस्सा है और ब्राउज़र-विशिष्ट फ़ंक्शन नहीं है - अधिक सुरक्षित है।


प्रदर्शन के लिहाज JSON.parseसे eval, कम से कम V8 (क्रोमियम का JS इंजन) से तेज है । स्रोत
पॉल

जवाबों:


110

यदि आप उपयोग करते हैं तो आप हमलों के प्रति अधिक संवेदनशील होते हैंeval : JSON जावास्क्रिप्ट का एक सबसेट है और json.parse सिर्फ JSON को पार्स करता है जबकि evalसभी JS अभिव्यक्तियों के लिए दरवाजा खुला छोड़ देता है।


"आप हमलों के प्रति अधिक संवेदनशील हैं" , मैं पूरी तरह से असहमत हूं!
हाइड्रोपर

4
क्षमा करें, माथियस, मुझे सहमत होना होगा। समस्या तब है जब आप "उपयोगकर्ता इनपुट" की व्याख्या करने के लिए eval () का उपयोग कर रहे हैं - जो आपके जावास्क्रिप्ट से कोई भी स्रोत बाहरी है (जिसमें आपके द्वारा कॉल किए गए सर्लेट या अन्य वेब सेवाओं से लौटाया गया मान भी शामिल है)। आप यह गारंटी नहीं दे सकते कि उपयोगकर्ताओं ने दुर्भावनापूर्ण जावास्क्रिप्ट या तो सीधे अपने क्लाइंट ऐप में प्रवेश नहीं किया है, या अप्रत्यक्ष रूप से सर्वर के डेटाबेस में संग्रहीत डेटा के कारण और फिर AJAX- शैली कॉल के माध्यम से आपके प्रोग्राम में पास हुआ। आपको "भ्रमित डिप्टी" हमलों से बचने के लिए व्यक्तिगत क्षेत्रों को मान्य करने की आवश्यकता हो सकती है, लेकिन JSON.parse का उपयोग करना एक अच्छा पहला कदम है।
जैकलोथनटन

1
@ हेड्रो अवधारणा का संक्षिप्त प्रमाण: कोशिश करें eval('alert(1)');
वलेरियो बूज

37

सभी JSON.parseकार्यान्वयन सबसे अधिक संभावना उपयोग करते हैंeval()

JSON.parseडगलस क्रॉकफोर्ड के समाधान पर आधारित है , जो लाइन 497eval() पर वहीं उपयोग करता है ।

// 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
हाँ, सिवाय इसके कि लाइन के ठीक पहले यह सत्यापित करता है कि यह एक सुरक्षित और वैध स्ट्रिंग है।
22

6
मैंने JSON.parse()अपने लिनक्स मिंट सिस्टम पर फ़ायरफ़ॉक्स 28 और क्रोमियम 33 में परीक्षण किया । यह eval()फ़ायरफ़ॉक्स की तरह 2x था और क्रोमियम में 4x जितना तेज़ था। मुझे यकीन नहीं है कि आप किस स्रोत कोड को पोस्ट कर रहे हैं, लेकिन वे मेरे ब्राउज़रों में समान नहीं हैं।
jbo5112

@plodder "लाभ" शायद उस सत्यापन को करने के लिए सस्ता नहीं है।
mmm

2
आधुनिक ब्राउज़र देशी JSON.parse()कार्यान्वयन प्रदान करता है जो सुरक्षित और तेज़ गति वाले eval()पार्सर की तुलना में अधिक सुरक्षित है ।
मोहम्मद अलहश

15

सभी ब्राउज़रों के पास देशी JSON समर्थन नहीं है इसलिए ऐसे समय होंगे जहां आपको eval() JSON स्ट्रिंग का उपयोग करने की आवश्यकता होगी । से उपयोग JSON पार्सर http://json.org कि हैंडल सब कुछ आप के लिए बहुत आसान है।

Eval() एक बुराई है लेकिन कुछ ब्राउज़रों के खिलाफ यह एक आवश्यक बुराई है लेकिन आप इसे कहाँ से बचा सकते हैं, ऐसा करें !!!!!


12

JSON.parse () और eval () स्वीकार करेंगे के बीच एक अंतर है। इस पर स्पष्ट प्रयास करें:

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

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

इस उदाहरण को देखें ।


1
eval काम नहीं करता है क्योंकि यह कोड स्टेटमेंट के रूप में स्ट्रिंग को पार्स करता है और इस प्रकार, "{...}" को एक मूल्य घोषणा अभिव्यक्ति के बजाय कोड अभिव्यक्ति के रूप में मानता है। यदि आप उदाहरण के लिए अस्पष्टता ("[{....}]") को हटाते हैं, तो अभिव्यक्ति की प्रकृति पर कोई संदेह नहीं है और eval पार्स किए गए
ओब्जेक्ट

1
हाँ। परंपरागत रूप से, x कोष्ठकों द्वारा लपेटा जाएगा: eval ("(" + x + ")")। मैंने जो कहा वह अभी भी खड़ा है: JSON.parse () का उपयोग करते समय कोई अस्पष्टता नहीं है।
जेफ लोरी

9

यदि आप JSON को पार्स करते हैं eval, तो आप स्ट्रिंग को पूरी तरह से कुछ भी शामिल करने की अनुमति दे रहे हैं, इसलिए केवल डेटा का एक सेट होने के बजाय, आप अपने आप को फ़ंक्शन कॉल, या जो कुछ भी निष्पादित कर सकते हैं।

इसके अलावा, JSON parseएक एडवेंचर पैरामीटर, रिवीवर को स्वीकार करता है, जो आपको निर्दिष्ट करता है कि कुछ मानों से कैसे निपटा जाए, जैसे कि डेटाटाइम्स ( यहां इनलाइन प्रलेखन में अधिक जानकारी और उदाहरण )


4

JSON, जावास्क्रिप्ट का एक सबसेट है। लेकिन evalपूरी जावास्क्रिप्ट भाषा का मूल्यांकन करता है, न कि केवल सबसे अच्छा जो JSON है।


सही है, मुझे पता है। क्या आप यह अनुमान लगा रहे हैं कि JSON.parse () केवल JSON का मूल्यांकन करता है और अन्य सभी आने वाले डेटा पर विफल रहता है? या क्या यह केवल एक आवरण है: var myObject = eval ('(' + responseText + ')'); ??
केविन मेजर

6
@ केविन मेजर: हां, मूल रूप से लागू किया गया JSON.parse(सीधे जावास्क्रिप्ट इंजन में लागू किया गया) केवल जेएसएन परसेंट करता है। लेकिन अन्य गैर-देशी कार्यान्वयन कुछ विवेक जांच करते हैं और फिर evalप्रदर्शन कारणों से उपयोग करते हैं।
गुमबो डिक्
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.