2009-12-03 20 views
83

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

उत्तर

97

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

+0

* "आप हमलों के लिए अधिक संवेदनशील हैं" *, मैं पूरी तरह से असहमत हूं! – Hydro

+2

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

+0

@ हाइड्रो अवधारणा का संक्षिप्त सबूत: 'eval (' चेतावनी (1) ') का प्रयास करें; '। –

4

JSON जावास्क्रिप्ट का बस एक उप-समूह है। लेकिन eval पूर्ण जावास्क्रिप्ट भाषा का मूल्यांकन करता है न कि बस जेएसओएन का सबसेट।

+0

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

+5

@ केविन मेजर: हां, मूल रूप से लागू 'JSON.parse' (सीधे जावास्क्रिप्ट इंजन में कार्यान्वित) केवल JSON पार्स करता है। लेकिन अन्य गैर-मूल रूप से कार्यान्वयन कुछ सैनिटी जांच करते हैं और फिर प्रदर्शन कारणों से 'eval' का उपयोग करते हैं। – Gumbo

9

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

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

13

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

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

29

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

JSON.parseDouglas Crockford's solution, जो eval()line 497 पर वहीं का उपयोग करता है पर आधारित है।

// 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 वाक्य रचना है।

+50

हाँ, सिवाय इसके कि उस पंक्ति से ठीक पहले यह सत्यापित करता है कि यह एक सुरक्षित और वैध स्ट्रिंग है। – nickf

+3

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

+0

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

9

JSON.parse() और eval() स्वीकार करने के बीच एक अंतर है। "{ShoppingCartName \": \ "shopping_cart: 2000 \

वर एक्स = \": "}" इस पर eval प्रयास करें

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

इस example देखें।

+1

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

+1

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

संबंधित मुद्दे