जब जावास्क्रिप्ट है eval () नहीं बुराई?


263

मैं कुछ जावास्क्रिप्ट कोड लिख रहा हूं ताकि उपयोगकर्ता द्वारा दर्ज किए गए कार्यों (स्प्रेडशीट जैसी कार्यक्षमता के लिए) को पार्स किया जा सके। सूत्र को पार्स करने के बाद मैं इसे जावास्क्रिप्ट में बदल सकता हूं और eval()परिणाम प्राप्त करने के लिए इस पर चला सकता हूं ।

हालाँकि, मैंने हमेशा इसका उपयोग करने से कतराया है eval()अगर मैं इससे बच सकता हूं क्योंकि यह बुराई है (और, सही या गलत, मैंने हमेशा सोचा है कि यह जावास्क्रिप्ट में और भी अधिक दुष्ट है, क्योंकि मूल्यांकन किए जाने वाले कोड को उपयोगकर्ता द्वारा बदला जा सकता है। )।

तो, जब यह उपयोग करने के लिए ठीक है?


5
अधिकांश JSON लाइब्रेरी वास्तव में हुड के तहत eval का उपयोग नहीं करते हैं, बिल्कुल सुरक्षा जोखिमों से बचाने के लिए।
सीन मैकमिलन

11
@ सीन - JQuery और प्रोटोटाइप दोनों का उपयोग eval (JQuery इसे नए फ़ंक्शन के माध्यम से उपयोग करता है)
प्लोडर

5
@plodder - आप अपनी जानकारी कहां प्राप्त कर रहे हैं? jQuery ने 1.4 के बाद से देशी JSON.parse () का उपयोग किया है (1/2010 में वापस)! खुद के लिए देखें: code.jquery.com/jquery-1.4.js
ken

3
"स्पष्ट रूप से किसी को JSON को पार्सल करने के लिए eval () का उपयोग करना होगा" - यह सच नहीं है, इसके विपरीत - किसी को JSON को पार्सल करने के लिए eval का उपयोग नहीं करना चाहिए! डगलस क्रॉकफॉर्ड्स (JSON के निर्माता) का उपयोग करें json2.js स्क्रिप्ट json.org से !
TMS

11
@ टोमास वहाँ है कि json2.js पार्सल JSON
tobyodavies

जवाबों:


262

मैं आपके प्रश्न के आधार को संबोधित करने के लिए एक क्षण लेना चाहूंगा - यह स्पष्ट () " बुराई " है। शब्द " बुराई ", जैसा कि प्रोग्रामिंग भाषा के लोगों द्वारा उपयोग किया जाता है, आमतौर पर "खतरनाक", या अधिक सटीक रूप से "सरल-दिखने वाली कमांड के साथ बहुत सारे नुकसान का कारण बन सकता है"। तो, कुछ खतरनाक का उपयोग करना कब ठीक है? जब आप जानते हैं कि खतरा क्या है, और जब आप उचित सावधानी बरत रहे हैं।

इस बिंदु पर, आइए हम eval () के उपयोग के खतरों को देखें। वहाँ शायद सब कुछ की तरह कई छोटे छिपे हुए खतरे हैं, लेकिन दो बड़े जोखिम - कारण eval () को बुराई माना जाता है - प्रदर्शन और कोड इंजेक्शन हैं।

  • प्रदर्शन - eval () दुभाषिया / संकलक चलाता है। यदि आपका कोड संकलित है, तो यह एक बड़ी हिट है, क्योंकि आपको रन-टाइम के बीच में संभवतः-भारी कंपाइलर को कॉल करना होगा। हालांकि, जावास्क्रिप्ट अभी भी ज्यादातर एक व्याख्या की गई भाषा है, जिसका अर्थ है कि सामान्य मामले में कॉलिंग इवेल () एक बड़ा प्रदर्शन हिट नहीं है (लेकिन नीचे मेरी विशिष्ट टिप्पणी देखें)।
  • कोड इंजेक्शन - eval () संभावित रूप से उन्नत विशेषाधिकार के तहत कोड की एक स्ट्रिंग चलाता है। उदाहरण के लिए, एक प्रोग्राम जो प्रशासक / रूट के रूप में चल रहा है, वह कभी भी इनपुट () इनपुट का उपयोग नहीं करना चाहेगा, क्योंकि वह इनपुट संभवतः "rm -rf / etc / important-file" या इससे भी बदतर हो सकता है। फिर से, एक ब्राउज़र में जावास्क्रिप्ट में वह समस्या नहीं है, क्योंकि प्रोग्राम वैसे भी उपयोगकर्ता के खाते में चल रहा है। सर्वर-साइड जावास्क्रिप्ट में वह समस्या हो सकती है।

अपने विशिष्ट मामले पर। जो मैं समझता हूं, आप स्वयं स्ट्रिंग्स उत्पन्न कर रहे हैं, इसलिए यह मानते हुए कि आप "rm -rf कुछ-महत्वपूर्ण" जैसी स्ट्रिंग की अनुमति नहीं देने के लिए सावधान हैं, कोई कोड इंजेक्शन जोखिम नहीं है (लेकिन कृपया याद रखें, यह बहुत बहुत है सामान्य मामले में यह सुनिश्चित करना कठिन है)। इसके अलावा, यदि आप ब्राउज़र में चल रहे हैं तो कोड इंजेक्शन एक बहुत मामूली जोखिम है, मेरा मानना ​​है।

प्रदर्शन के लिए, आपको वजन कम करना होगा जो कोडिंग में आसानी के खिलाफ है। यह मेरी राय है कि यदि आप फॉर्मूला पार्स कर रहे हैं, तो आप पार्स के दौरान परिणाम की गणना दूसरे पार्सर (एक अंदर वाला) () के बजाय कर सकते हैं। लेकिन eval () का उपयोग कर कोड करना आसान हो सकता है, और प्रदर्शन हिट शायद ध्यान देने योग्य नहीं होगा। ऐसा लगता है कि इस मामले में eval () किसी भी अन्य फ़ंक्शन से अधिक बुराई नहीं है जो संभवतः आपको कुछ समय बचा सकता है।


78
आप कोड के मुद्दे को संबोधित नहीं कर रहे हैं, जो कि डीबग करने के लिए कठिन होने का उपयोग करता है
bobobobo

48
यदि आप अपने उपयोगकर्ता के डेटा के बारे में चिंतित हैं तो कोड इंजेक्शन जावास्क्रिप्ट के लिए एक बहुत ही गंभीर मुद्दा है। इंजेक्ट कोड (ब्राउज़र में) चलेगा जैसे कि यह आपकी साइट से आया है, यह किसी भी प्रकार के शेनिगन को देता है जो उपयोगकर्ता मैन्युअल रूप से कर सकता है। यदि आप (तृतीय-पक्ष) कोड आपको पृष्ठ में प्रवेश करने की अनुमति देते हैं, तो यह आपके ग्राहक की ओर से चीजों को ऑर्डर कर सकता है, या उनके गुरुत्वाकर्षण को बदल सकता है, या वे आपकी साइट के माध्यम से जो कुछ भी कर सकते हैं। बहुत सावधान रहें। हैकर्स को अपने ग्राहकों को खुद को अपने सर्वर के रूप में देने के रूप में बुरा है।
सीन मैकमिलन

71
यदि डेटा आपके सर्वर और इसकी कुछ चीज़ों से आ रहा है जिसे आपने, डेवलपर ने उत्पन्न किया है, तो eval () का उपयोग करने में कोई बुराई नहीं है। असली नुकसान आपके द्वारा पढ़ी गई हर चीज पर विश्वास करना है। आप बहुत से लोगों को यह कहते हुए देख रहे हैं कि बुराई () बुराई है और उन्हें पता नहीं है कि सिवाय इसके कि वे इसे कहीं क्यों पढ़ते हैं।
विंस पानुकियो

42
@ सीन मैकमिलन: मैं आपको विश्वास दिलाना चाहता हूं, लेकिन अगर कोई eval()आपके सर्वर से जा रहे जावास्क्रिप्ट को इंटरसेप्ट करने और बदलने जा रहा है , तो वे पहली बार में पेज के स्रोत को भी बदल सकते हैं, और उपयोगकर्ता की जानकारी को भी नियंत्रित कर सकते हैं। । । मुझे अंतर नहीं दिखता।
वॉल्ट डब्ल्यू

20
"कोड इंजेक्शन - ... फिर से, एक ब्राउज़र में जावास्क्रिप्ट में वह समस्या नहीं है," और "इसके अलावा, यदि आप ब्राउज़र में चल रहे हैं तो कोड इंजेक्शन एक बहुत मामूली जोखिम है, मुझे विश्वास है।" क्या आप सुझाव दे रहे हैं कि ब्राउज़र में कोड-इंजेक्शन कोई समस्या नहीं है? XSS कई वर्षों से OWASP की शीर्ष 10 सूची में शीर्ष 3 वल्न्स पर चल रहा है।
माइक सैमुअल

72

eval()बुराई नहीं है। या, यदि यह है, तो यह उसी तरह से बुराई है जैसे प्रतिबिंब, फ़ाइल / नेटवर्क I / O, थ्रेडिंग, और IPC अन्य भाषाओं में "बुराई" है।

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


5
ऐसा एक उद्देश्य अनुकूलित कोड उत्पन्न करना हो सकता है जो या तो बहुत लंबा होगा या हाथ से लिखने के लिए दोहरावदार होगा। जिस तरह का सामान, LISP में, मैक्रो के लिए कहेंगे।
wberry

5
यह ऐसी सामान्य सलाह है कि इसे कोड के किसी भी ब्लॉक पर लागू किया जा सकता है। यह वास्तव में इस प्रश्न के लिए कुछ भी नहीं जोड़ता है; विशेष रूप से, यह यहां आने वाले किसी व्यक्ति को यह निर्धारित करने में मदद नहीं करता है कि उनका विशेष उपयोग समस्याग्रस्त है या नहीं।
jpmc26

2
तेज़, सरल, अधिक स्पष्ट ... यह उत्तर सुरक्षा निहितार्थ को पर्याप्त रूप से कवर नहीं करता है।
रूड हेलडरमैन

55

जब आप स्रोत पर भरोसा करते हैं।

JSON के मामले में, स्रोत से छेड़छाड़ करना कम या ज्यादा कठिन है, क्योंकि यह आपके द्वारा नियंत्रित वेब सर्वर से आता है। जब तक JSON में स्वयं कोई उपयोगकर्ता अपलोड किया गया डेटा नहीं है, तब तक eval का उपयोग करने के लिए कोई बड़ी खामी नहीं है।

अन्य सभी मामलों में मैं यह सुनिश्चित करने के लिए महान लंबाई तक जाऊँगा कि उपयोगकर्ता द्वारा आपूर्ति किए गए डेटा को eval () में फीड करने से पहले मेरे नियमों के अनुरूप है।


13
एक जैसन स्ट्रिंग को हमेशा eval () में उपयोग करने से पहले json व्याकरण के खिलाफ परीक्षण किया जाना चाहिए। इसलिए json string "{foo: alert ('XSS')}" अलर्ट ('XSS') के बाद से नहीं गुजरेगा। यह उचित मूल्य नहीं है।
गंबू 3

3
खैर, HTTPS का उपयोग करें। OTOH: मैन-इन-द-बीच उद्यान विविधता वेब ऐप के लिए विशिष्ट आक्रमण परिदृश्य नहीं है, जबकि क्रॉस-साइट-स्क्रिप्टिंग है।
टॉमालक

7
evalयह भी सभी वैध JSON तार को सही ढंग से पार्स नहीं करेगा। उदाहरण के लिए, JSON.parse(' "\u2028" ') === "\u2028"लेकिन eval(' "\u2028" ')एक अपवाद उठाता है क्योंकि U + 2028 जावास्क्रिप्ट में एक नई रेखा है, लेकिन यह एक नई पंक्ति नहीं है जहां तक ​​JSON का संबंध है।
माइक सैमुअल

1
@ जस्टिन - यदि प्रोटोकॉल से समझौता किया जाता है, तो ठीक है, आमतौर पर प्रारंभिक पेज लोड उसी प्रोटोकॉल पर भेजा गया होगा, और फिर यह एक मूट बिंदु है क्योंकि क्लाइंट पहले से ही उतना ही समझौता है जितना संभवतः हो सकता है।
एंटीइनोम

1
सुंदर ने कहा @Tomalak, मैंने अभी अपने उत्तर में इसका उल्लेख किया है! बहुत बढ़िया!
NiCk Newman

25

चलो असली लोगों को मिलता है:

  1. हर बड़े ब्राउज़र में अब एक अंतर्निहित कंसोल होता है, जिसे आपके है-बी हैकर बहुतायत के साथ किसी भी फ़ंक्शन को किसी भी मूल्य पर लागू करने के लिए उपयोग कर सकते हैं - वे एक स्पष्ट कथन का उपयोग करने के लिए क्यों परेशान होंगे - भले ही वे कर सकते हों?

  2. यदि जावास्क्रिप्ट की 2000 लाइनों को संकलित करने में 0.2 सेकंड का समय लगता है, अगर मैं JSON की चार लाइनों का उपयोग करता हूं तो मेरा प्रदर्शन गिरावट क्या है?

यहां तक ​​कि क्रोकफोर्ड का 'बुराई है बुराई' के लिए स्पष्टीकरण कमजोर है।

eval ईविल है, eval function जावास्क्रिप्ट का सबसे अधिक दुरुपयोग किया गया फीचर है। इससे बचो

जैसा कि क्रॉकफोर्ड खुद कह सकते हैं "इस तरह का बयान तर्कहीन न्यूरोसिस उत्पन्न करता है। इसे न खरीदें।"

Eval को समझना और यह जानना कि यह कब उपयोगी हो सकता है। उदाहरण के लिए, eval सर्वर प्रतिक्रियाओं का मूल्यांकन करने के लिए एक समझदार उपकरण है जो आपके सॉफ़्टवेयर द्वारा उत्पन्न किए गए थे।

BTW: Prototyp.js सीधे eval को पांच बार (evalJSON () और evalResponse () सहित) कॉल करता है। jQuery parseJSON (फ़ंक्शन निर्माणकर्ता के माध्यम से) में इसका उपयोग करता है।


10
JQuery ब्राउज़र के अंतर्निहित JSON.parse फ़ंक्शन का उपयोग करता है यदि उपलब्ध हो (जो बहुत तेज़ और सुरक्षित है), केवल एक बैकबैक तंत्र के रूप में eval का उपयोग कर रहा है। बयान "बुराई बुराई है" एक काफी अच्छा दिशानिर्देश है।
जजमोंट्स

30
"हर प्रमुख ब्राउज़र में अब एक कंसोल बनाया गया है ..."। कोड इंजेक्शन एक समस्या है जब एक उपयोगकर्ता उस कोड को दर्ज कर सकता है जो किसी अन्य उपयोगकर्ता के ब्राउज़र में चलाया जाता है। ब्राउज़र कंसोल खुद से एक उपयोगकर्ता को दूसरे उपयोगकर्ता ब्राउज़र में कोड चलाने की अनुमति नहीं देते हैं, इसलिए वे यह तय करते समय अप्रासंगिक हैं कि क्या यह कोड इंजेक्शन के खिलाफ सुरक्षा के लायक है।
माइक सैमुअल

28
"हर बड़े ब्राउज़र में अब एक कंसोल बनाया गया है ... वे एक स्पष्ट विवरण का उपयोग करने के लिए क्यों परेशान होंगे?" - आप निशान से दूर हैं। मेरा सुझाव है कि आप उत्तर को संपादित करें। कोड को इंजेक्ट करने के लिए एक उपयोगकर्ता की क्षमता जो दूसरे के ब्राउज़र में चल सकती है, एक प्रमुख मुद्दा है। और यह वह जगह है जहाँ आपको वास्तव में वास्तविक होने की आवश्यकता है।
अक्किशोर

5
@ अंकिशोर, मैं सराहना करूंगा यदि आप एक वास्तविक जीवन उदाहरण के साथ आते हैं जो आपके अधिक कथनों का समर्थन करता है।
आकाश काव

7
@ आकाशवाणी आप जो महसूस करने में असफल हो रहे हैं, वह यह है कि अगर मैं अपने कमेंट बॉक्स में जावास्क्रिप्ट जमा करता हूं, और वह जावास्क्रिप्ट डेटाबेस में आता है। जब कोई अन्य उपयोगकर्ता उस टिप्पणी को देखता है (जिसमें मैंने जावास्क्रिप्ट डाल दिया है), तो जब यह प्रस्तुत किया जाता है तो eval उस जावास्क्रिप्ट को ले जाएगा, और दुभाषिया का उपयोग करके इसका मूल्यांकन करेगा, जिससे मेरा एम्बेडेड जावास्क्रिप्ट दूसरे उपयोगकर्ता के ब्राउज़र पर निष्पादित होगा। ऐसा करने से, मैं सभी प्रकार की जानकारी प्राप्त कर सकता हूं। उनका उपयोगकर्ता नाम, डेटाबेस में उनका यूजर आईडी, उनका ई-मेल पता आदि। यह कोई कठिन जवाब नहीं है, यदि आपके पास गोगल्ड एक्सएसएस था, तो आप लगभग 10 सेकंड में देखेंगे कि यह एक मुद्दा क्यों है।
काइल रिक्टर

18

मैं पालन करने के लिए करते हैं Crockford की सलाह के लिए eval(), और यह पूरी तरह से बचें। यहां तक ​​कि ऐसे तरीकों की आवश्यकता होती है जो ऐसा नहीं करते हैं। उदाहरण के लिए, setTimeout()आप eval के बजाय एक फ़ंक्शन पास करने की अनुमति देता है।

setTimeout(function() {
  alert('hi');
}, 1000);

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


2
मुझे लगता है कि सर्वर साइड में JSON फॉर्मैटर में कीड़े निश्चित रूप से एक मुद्दा है। क्या सर्वर से प्रतिक्रिया किसी भी तरह के उपयोगकर्ता द्वारा प्रस्तुत पाठ पर निर्भर करती है? तो फिर तुम XSS के लिए देखना होगा।
स्वाइलियट्स

3
यदि आपके वेबसर्वर को HTTPS के माध्यम से प्रमाणित नहीं किया गया है, तो आप किसी प्रकार के मैन-इन-द-मिडल अटैक से पीड़ित हो सकते हैं, जहां एक अन्य होस्ट अनुरोध को स्वीकार करता है और अपना डेटा भेजता है।
बेन कंबाइ डेका

11
यदि कोई व्यक्ति बीच-बीच में हमला कर सकता है, तो वह आसानी से आपकी स्क्रिप्ट पर कुछ भी इंजेक्ट कर सकता है।
el.pescado

10
आपको अपने जावास्क्रिप्ट कोड पर बिल्कुल भी भरोसा नहीं करना चाहिए ... आप क्लाइंट की तरफ से चलने वाली किसी भी चीज पर भरोसा नहीं करते ... अगर कोई व्यक्ति बीच-बीच में हमला करता है तो वह आपके जोंस ऑब्जेक्ट्स के साथ गड़बड़ क्यों करेगा? वह आपके लिए एक अलग वेबपेज और अलग-अलग js फ़ाइलों की सेवा कर सकता है ...
Calmarius

5
मैं व्यक्तिगत रूप से इस तर्क को नापसंद करता हूं "हमेशा ऐसा करने के अन्य तरीके होते हैं।" उदाहरण के लिए, आप यह भी कह सकते हैं कि ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग से बचने के हमेशा तरीके हैं। इसका मतलब यह नहीं है कि यह एक बढ़िया विकल्प नहीं है। यदि आप स्पष्ट समझते हैं और यह खतरे हैं, तो यह सही स्थितियों में उपयोग करने के लिए एक महान उपकरण हो सकता है।
dallin

4

मैंने देखा कि लोग बुराई का उपयोग नहीं करने की वकालत करते हैं, क्योंकि यह बुराई है , लेकिन मैंने देखा कि वही लोग फंक्शन और सेटटाइमआउट का गतिशील रूप से उपयोग करते हैं, इसलिए वे हुड के नीचे eval का उपयोग करते हैं : D

BTW, अगर आपका सैंडबॉक्स पर्याप्त सुनिश्चित नहीं है (उदाहरण के लिए, यदि आप किसी साइट पर काम कर रहे हैं जो कोड इंजेक्शन की अनुमति देता है) तो आपकी समस्याओं का अंतिम सबूत है। सुरक्षा का मूल नियम यह है कि सभी इनपुट बुराई है, लेकिन जावास्क्रिप्ट के मामले में भी जावास्क्रिप्ट ही बुराई हो सकती है, क्योंकि जावास्क्रिप्ट में आप किसी भी फ़ंक्शन को अधिलेखित कर सकते हैं और आप यह सुनिश्चित नहीं कर सकते कि आप वास्तविक का उपयोग कर रहे हैं, इसलिए, यदि आपके सामने कोई दुर्भावनापूर्ण कोड शुरू होता है, तो आप किसी भी जावास्क्रिप्ट में निर्मित फ़ंक्शन पर भरोसा नहीं कर सकते: डी

अब इस पोस्ट का उपसंहार है:

यदि आपको वास्तव में इसकी आवश्यकता है (समय निष्कासन का 80% आवश्यक नहीं है) और आप सुनिश्चित हैं कि आप क्या कर रहे हैं, बस eval (या बेहतर फ़ंक्शन का उपयोग करें;), क्लोज़र और OOP 80/90% को कवर करते हैं; ऐसी स्थिति में जहां eval को किसी अन्य प्रकार के तर्क का उपयोग करके बदला जा सकता है, बाकी गतिशील रूप से उत्पन्न कोड है (उदाहरण के लिए, यदि आप एक दुभाषिया लिख ​​रहे हैं) और जैसा कि आपने पहले ही JSON का मूल्यांकन करते हुए कहा था (यहाँ आप Crockford सुरक्षित मूल्यांकन का उपयोग कर सकते हैं;)


और जैसा कि क्रॉकफोर्ड ने खुद बताया है , वर्तमान वेब ब्राउज़रों में एक अंतर्निहित फ़ंक्शन JSON.parse है
रूड हेलडरमैन

4

Eval संकलन का पूरक है जो कोड को गति देने में उपयोग किया जाता है। अस्थायी रूप से मेरा मतलब है कि आप एक सरल टेम्पलेट जनरेटर लिखते हैं जो उपयोगी टेम्पलेट कोड उत्पन्न करता है जो विकास की गति को बढ़ाता है।

मैंने एक फ्रेमवर्क लिखा है, जहाँ डेवलपर्स EVAL का उपयोग नहीं करते हैं, लेकिन वे हमारे फ्रेमवर्क का उपयोग करते हैं और बदले में टेम्प्लेट उत्पन्न करने के लिए फ्रेमवर्क को EVAL का उपयोग करना पड़ता है।

ईवीएएल का प्रदर्शन निम्नलिखित विधि का उपयोग करके बढ़ाया जा सकता है; स्क्रिप्ट निष्पादित करने के बजाय, आपको एक फ़ंक्शन वापस करना होगा।

var a = eval("3 + 5");

इसका आयोजन होना चाहिए

var f = eval("(function(a,b) { return a + b; })");

var a = f(3,5);

कैशिंग एफ निश्चित रूप से गति में सुधार करेगा।

साथ ही क्रोम ऐसे कार्यों को बहुत आसानी से डिबगिंग की अनुमति देता है।

सुरक्षा के संबंध में, eval का उपयोग करना या न करना शायद ही कोई फर्क पड़ेगा,

  1. सबसे पहले, ब्राउज़र एक सैंडबॉक्स में पूरी स्क्रिप्ट को आमंत्रित करता है।
  2. कोई भी कोड जो EVAL में बुराई है, ब्राउज़र में ही बुराई है। हमलावर या कोई भी आसानी से डोम में एक स्क्रिप्ट नोड इंजेक्षन कर सकता है और कुछ भी कर सकता है यदि वह कुछ भी निकाल सकता है। EVAL का उपयोग नहीं करने से कोई फर्क नहीं पड़ेगा।
  3. यह ज्यादातर खराब सर्वर-साइड सुरक्षा है जो हानिकारक है। सर्वर पर खराब कुकीज़ सत्यापन या खराब एसीएल कार्यान्वयन सबसे हमलों का कारण बनता है।
  4. जावा के मूल कोड में हाल ही में जावा भेद्यता आदि थी। जावास्क्रिप्ट एक सैंडबॉक्स में चलाने के लिए डिज़ाइन किया गया था, जबकि ऐपलेट को सैंडबॉक्स के बाहर प्रमाण पत्र के साथ चलाने के लिए डिज़ाइन किया गया था, आदि जो कमजोरियों और कई अन्य चीजों को जन्म देते हैं।
  5. ब्राउज़र की नकल के लिए कोड लिखना मुश्किल नहीं है। आपको बस इतना करना है कि अपने पसंदीदा उपयोगकर्ता एजेंट स्ट्रिंग के साथ सर्वर से HTTP अनुरोध करें। सभी परीक्षण उपकरण वैसे भी ब्राउज़रों का मज़ाक उड़ाते हैं; यदि कोई हमलावर आपको नुकसान पहुंचाना चाहता है, तो EVAL उनका अंतिम उपाय है। आपके पास सर्वर-साइड सुरक्षा से निपटने के लिए उनके पास कई अन्य तरीके हैं।
  6. ब्राउज़र डोम में फ़ाइलों तक पहुंच नहीं है और उपयोगकर्ता नाम नहीं है। वास्तव में मशीन पर कुछ भी नहीं है कि eval तक पहुँच दे सकता है।

यदि आपके सर्वर-साइड की सुरक्षा किसी के लिए भी कहीं से भी हमला करने के लिए पर्याप्त है, तो आपको EVAL के बारे में चिंता नहीं करनी चाहिए। जैसा कि मैंने उल्लेख किया है, अगर EVAL मौजूद नहीं होता, तो हमलावरों के पास आपके ब्राउज़र की EVAL क्षमता के बावजूद आपके सर्वर में हैक करने के लिए कई उपकरण होते हैं।

पहले से उपयोग नहीं की जाने वाली चीज़ के आधार पर जटिल स्ट्रिंग प्रसंस्करण करने के लिए कुछ टेम्पलेट्स उत्पन्न करने के लिए केवल एवल अच्छा है। उदाहरण के लिए, मैं पसंद करूंगा

"FirstName + ' ' + LastName"

विरोध के रूप में

"LastName + ' ' + FirstName"

मेरे प्रदर्शन नाम के रूप में, जो डेटाबेस से आ सकता है और जो हार्डकोड नहीं है।


आप eval के बजाय फ़ंक्शन का उपयोग कर सकते हैं - function (first, last) { return last + ' ' + first }
कोनराड बोरोस्की

कॉलम के नाम डेटाबेस से आते हैं।
आकाश काव

3
इसका खतरा evalज्यादातर अन्य उपयोगकर्ताओं को है । मान लें कि आपके पास एक सेटिंग पृष्ठ है, और यह आपको यह निर्धारित करने की अनुमति देता है कि आपका नाम दूसरों को कैसे दिखाई देता है। मान लीजिए कि आप इसे लिखते समय बहुत स्पष्ट रूप से नहीं सोच रहे थे, इसलिए आपके चयनित बॉक्स में जैसे विकल्प हैं <option value="LastName + ' ' + FirstName">Last First</option>। मैं अपने देव टूल्स को खोलता हूं, valueएक विकल्प को alert('PWNED!')बदलकर, बदले हुए विकल्प का चयन करें और फॉर्म सबमिट करें। अब, किसी भी समय कोई अन्य व्यक्ति मेरा प्रदर्शन नाम देख सकता है, वह कोड चलाता है।
cHao

@cHao, जिस बारे में आप बात कर रहे हैं, वह खराब सर्वर साइड सुरक्षा का उदाहरण है, सर्वर को कभी भी ऐसे डेटा को स्वीकार नहीं करना चाहिए जिसे किसी के ब्राउज़र में कोड के रूप में निष्पादित किया जा सकता है। एक बार फिर, आप खराब सर्वर साइड सुरक्षा की अवधारणा को समझने में विफल रहे हैं।
आकाश काव

1
यदि आप चाहें, तो आप सर्वर-साइड सुरक्षा के बारे में सचेत कर सकते हैं, लेकिन संपूर्ण बिंदु evalकोड को निष्पादित करना है जो आपके द्वारा लिखी गई स्क्रिप्ट का हिस्सा नहीं है। यदि आपको ऐसा करने की शक्ति की आवश्यकता नहीं है (और आप लगभग कभी नहीं करते हैं), तो बचने evalसे समस्याओं की एक पूरी श्रेणी से बाहर निकलने में मदद मिलती है। अगर आपके सर्वर-साइड कोड सही से कम है तो यह अच्छी बात है।
cHao

4

जब क्रोम में डीबगिंग (v28.0.1500.72), मैंने पाया कि वैरिएबल बंद होने के लिए बाध्य नहीं हैं यदि वे एक नेस्टेड फ़ंक्शन में उपयोग नहीं किए जाते हैं जो क्लोजर का उत्पादन करता है। मुझे लगता है, कि जावास्क्रिप्ट इंजन का एक अनुकूलन है।

लेकिन : जब eval()किसी फ़ंक्शन के अंदर उपयोग किया जाता है जो एक बंद होने का कारण बनता है, तो बाहरी कार्यों के सभी चर बंद होने के लिए बाध्य होते हैं, भले ही उनका उपयोग न किया गया हो। यदि किसी के पास यह परीक्षण करने का समय है कि क्या मेमोरी लीक का उत्पादन किया जा सकता है, तो कृपया मुझे नीचे एक टिप्पणी छोड़ दें।

यहाँ मेरा परीक्षण कोड है:

(function () {
    var eval = function (arg) {
    };

    function evalTest() {
        var used = "used";
        var unused = "not used";

        (function () {
            used.toString();   // Variable "unused" is visible in debugger
            eval("1");
        })();
    }

    evalTest();
})();

(function () {
    var eval = function (arg) {
    };

    function evalTest() {
        var used = "used";
        var unused = "not used";

        (function () {
            used.toString();   // Variable "unused" is NOT visible in debugger
            var noval = eval;
            noval("1");
        })();
    }

    evalTest();
})();

(function () {
    var noval = function (arg) {
    };

    function evalTest() {
        var used = "used";
        var unused = "not used";

        (function () {
            used.toString();    // Variable "unused" is NOT visible in debugger
            noval("1");
        })();
    }

    evalTest();
})();

जो बात मैं यहाँ बताना चाहता हूँ, वह यह है कि eval () जरूरी नहीं कि मूल eval()फ़ंक्शन को संदर्भित करे । यह सब फ़ंक्शन के नाम पर निर्भर करता है । इसलिए जब मूल निवासी eval()को एक उपनाम नाम (कहते हैं var noval = eval;और फिर एक आंतरिक फ़ंक्शन में noval(expression);) के साथ बुलाया जाता है, तो उसका मूल्यांकन expressionविफल हो सकता है जब यह उन चर को संदर्भित करता है जो बंद होने का हिस्सा होना चाहिए, लेकिन वास्तव में नहीं है।



3

जमीनी स्तर

यदि आपने कोड को बनाया या पवित्र किया है eval, तो यह कभी भी बुराई नहीं है

थोड़ा और विस्तृत

evalयदि क्लाइंट द्वारा प्रस्तुत किए गए इनपुट का उपयोग करके सर्वर पर चल रहा है, जो डेवलपर द्वारा नहीं बनाया गया था या जो डेवलपर द्वारा sanitized नहीं था , तो यह बुराई है

evalहै बुराई नहीं है, ग्राहक पर चल रहा है , भले ही ग्राहक द्वारा तैयार की गई unsanitized इनपुट का उपयोग

जाहिर है कि आपको हमेशा इनपुट को सैनिटाइज करना चाहिए , क्योंकि आपका कोड क्या खाता है, इस पर कुछ नियंत्रण होना चाहिए

विचार

ग्राहक किसी भी मनमाने कोड को चला सकते हैं, जिसे वे चाहते हैं, भले ही डेवलपर ने उसे कोड न किया हो; यह न केवल के लिए सच है क्या evaled है, लेकिन करने के लिए कॉल evalही


2

एकमात्र उदाहरण जब आपको eval () का उपयोग करना चाहिए, जब आपको फ्लाई पर डायनेमिक JS चलाने की आवश्यकता हो। मैं JS की बात कर रहा हूँ कि आप सर्वर से एसिंक्रोनसली डाउनलोड करें ...

... और 10 में से 9 बार आप आसानी से ऐसा करने से बच सकते हैं।


आजकल, सर्वर से अतुल्यकालिक रूप से जावास्क्रिप्ट को लोड करने के अन्य (और बेहतर) तरीके हैं: w3bits.com/async-javascript
Ruud Helderman

1

evalशायद ही कभी सही विकल्प है। हालांकि ऐसे कई उदाहरण हो सकते हैं जहां आप एक स्क्रिप्ट को एक साथ समेटकर और उसे मक्खी पर चलाकर पूरा कर सकते हैं, जिसे आप पूरा कर सकते हैं, आमतौर पर आपके पास अपने निपटान में बहुत अधिक शक्तिशाली और रख-रखाव वाली तकनीकें हैं: साहचर्य-सरणी संकेतन ( obj["prop"]जैसा है obj.prop) , क्लोजर, ऑब्जेक्ट-ओरिएंटेड तकनीक, फंक्शनल तकनीक - इनका उपयोग करें।


1

जहां तक ​​क्लाइंट स्क्रिप्ट जाती है, मुझे लगता है कि सुरक्षा का मुद्दा एक म्यूट प्वाइंट है। ब्राउज़र में भरी हुई सब कुछ हेरफेर के अधीन है और इस तरह से व्यवहार किया जाना चाहिए। एक eval () स्टेटमेंट का उपयोग करने में शून्य जोखिम होता है जब जावास्क्रिप्ट कोड को निष्पादित करने और डोम में वस्तुओं को हेरफेर करने के बहुत आसान तरीके होते हैं, जैसे कि आपके ब्राउज़र में URL बार।

javascript:alert("hello");

अगर कोई अपने DOM में हेरफेर करना चाहता है, तो मैं कहता हूं कि दूर स्विंग करो। किसी भी प्रकार के हमले को रोकने के लिए सुरक्षा हमेशा सर्वर अनुप्रयोग, अवधि की जिम्मेदारी होनी चाहिए।

व्यावहारिक दृष्टिकोण से, एक ऐसी स्थिति में एक eval () का उपयोग करने का कोई लाभ नहीं है जहां चीजें अन्यथा की जा सकती हैं। हालांकि, ऐसे विशिष्ट मामले हैं जहां एक स्पष्ट SHOULD का उपयोग किया जाना चाहिए। जब ऐसा होता है, तो यह निश्चित रूप से पृष्ठ को उड़ाने के जोखिम के बिना किया जा सकता है।

<html>
    <body>
        <textarea id="output"></textarea><br/>
        <input type="text" id="input" />
        <button id="button" onclick="execute()">eval</button>

        <script type="text/javascript">
            var execute = function(){
                var inputEl = document.getElementById('input');
                var toEval = inputEl.value;
                var outputEl = document.getElementById('output');
                var output = "";

                try {
                    output = eval(toEval);
                }
                catch(err){
                    for(var key in err){
                        output += key + ": " + err[key] + "\r\n";
                    }
                }
                outputEl.value = output;
            }
        </script>
    <body>
</html>

6
"जावास्क्रिप्ट (या DOM में ऑब्जेक्ट्स को हेरफेर करने के लिए बहुत आसान तरीके हैं) जब एक eval () स्टेटमेंट का उपयोग करने में शून्य जोखिम होता है"। कोड इंजेक्शन एक समस्या है जब एक उपयोगकर्ता उस कोड को दर्ज कर सकता है जो किसी अन्य उपयोगकर्ता के ब्राउज़र में चलाया जाता है। ब्राउज़र कंसोल खुद से एक उपयोगकर्ता को दूसरे उपयोगकर्ता ब्राउज़र में कोड चलाने की अनुमति नहीं देते हैं, इसलिए वे यह तय करते समय अप्रासंगिक हैं कि क्या यह कोड इंजेक्शन के खिलाफ सुरक्षा के लायक है।
माइक सैमुअल

<head></head>आवश्यक नहीं है, भले ही खाली हो?
पीटर मोर्टेंसन

2
यह उत्तर पूरी तरह से XSS के जोखिमों की अनदेखी करता है ।
रूड हेलडरमैन

1

बाहरी साइड स्क्रिप्ट जैसे कि sql या influxdb या mongo से निपटने पर सर्वर साइड इवल उपयोगी है। जहां रनटाइम पर कस्टम सत्यापन आपकी सेवाओं को फिर से तैनात किए बिना बनाया जा सकता है।

उदाहरण के लिए मेटाडेटा के साथ एक उपलब्धि सेवा

{
  "568ff113-abcd-f123-84c5-871fe2007cf0": {
    "msg_enum": "quest/registration",
    "timely": "all_times",
    "scope": [
      "quest/daily-active"
    ],
    "query": "`SELECT COUNT(point) AS valid from \"${userId}/dump/quest/daily-active\" LIMIT 1`",
    "validator": "valid > 0",
    "reward_external": "ewallet",
    "reward_external_payload": "`{\"token\": \"${token}\", \"userId\": \"${userId}\", \"amountIn\": 1, \"conversionType\": \"quest/registration:silver\", \"exchangeProvider\":\"provider/achievement\",\"exchangeType\":\"payment/quest/registration\"}`"
  },
  "efdfb506-1234-abcd-9d4a-7d624c564332": {
    "msg_enum": "quest/daily-active",
    "timely": "daily",
    "scope": [
      "quest/daily-active"
    ],
    "query": "`SELECT COUNT(point) AS valid from \"${userId}/dump/quest/daily-active\" WHERE time >= '${today}' ${ENV.DAILY_OFFSET} LIMIT 1`",
    "validator": "valid > 0",
    "reward_external": "ewallet",
    "reward_external_payload": "`{\"token\": \"${token}\", \"userId\": \"${userId}\", \"amountIn\": 1, \"conversionType\": \"quest/daily-active:silver\", \"exchangeProvider\":\"provider/achievement\",\"exchangeType\":\"payment/quest/daily-active\"}`"
  }
}

जो तब अनुमति देते हैं,

  • ऑब्जेक्ट / वैल्यू के सीधे इंजेक्शन एक शाब्दिक स्ट्रिंग में एक json में, टेम्प्लेटिंग ग्रंथों के लिए उपयोगी

  • एक तुलनित्र के रूप में उपयोग किया जा सकता है, हम कहते हैं कि हम सीएमएस में खोज या घटनाओं को मान्य करने के लिए नियम बनाते हैं

इस का कोंन:

  • कोड में त्रुटियां हो सकती हैं और सेवा में चीजों को तोड़ सकते हैं, अगर पूरी तरह से परीक्षण नहीं किया गया है।

  • यदि कोई हैकर आपके सिस्टम पर स्क्रिप्ट लिख सकता है, तो आप बहुत अधिक खराब हैं।

  • अपनी स्क्रिप्ट को मान्य करने का एक तरीका यह है कि आपकी स्क्रिप्ट का हैश कहीं सुरक्षित है, इसलिए आप चलने से पहले उन्हें देख सकते हैं।


अच्छा लगा। जब मैंने सवाल पूछा तो मैं सर्वर-साइड जेएस के बारे में भी नहीं सोच रहा था।
रिचर्ड टर्नर

1

मुझे लगता है कि eval के किसी भी मामले को सही ठहराया जाना दुर्लभ होगा। आप यह सोचकर इसका उपयोग करने की अधिक संभावना रखते हैं कि यह आपके द्वारा उपयोग किए जाने की तुलना में उचित है जब यह वास्तव में उचित हो।

सुरक्षा के मुद्दे सबसे प्रसिद्ध हैं। लेकिन यह भी ध्यान रखें कि जावास्क्रिप्ट JIT संकलन का उपयोग करता है और यह निष्कासन के साथ बहुत खराब काम करता है। एवर कुछ हद तक संकलक के ब्लैकबॉक्स की तरह है, और जावास्क्रिप्ट को समय से पहले (कुछ हद तक) कोड की भविष्यवाणी करने में सक्षम होना चाहिए ताकि सुरक्षित रूप से और सही ढंग से प्रदर्शन अनुकूलन और स्कूपिंग लागू हो सके। कुछ मामलों में, प्रदर्शन का प्रभाव दूसरे कोड को भी प्रभावित कर सकता है।

यदि आप अधिक जानना चाहते हैं: https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch2.md#eval


0

यदि आप evalफ़ंक्शन पर पास किए गए कोड पर पूर्ण नियंत्रण रखते हैं, तो इसका उपयोग करना ठीक है ।


2
यदि आप जिस चीज़ से गुजर रहे हैं eval, उस पर आपका पूरा नियंत्रण है , तो बड़ा सवाल यह बन जाता है कि असली जेएस के बजाय इसके लिए एक स्ट्रिंग होने का क्या मतलब है?
cHao

@ CHao उदाहरण के लिए, यदि आपके पास एक बड़ा गेम-एप्लिकेशन (5-10MB जावास्क्रिप्ट) है, तो पहले एक साधारण फास्ट-लोडिंग AJAX- प्रीलोडर (1kb) का निर्माण करना बेहतर है, जो एक लोडिंग को प्रदर्शित करते हुए बड़े मेन-स्क्रिप्ट को लोड करता है। बार या कुछ इसी तरह। डाउनलोड करने के बाद आप लोड किए गए गेम-एप्लिकेशन-स्क्रिप्ट को चलाने के लिए "eval (स्रोत)" या बेहतर "नया फ़ंक्शन (स्रोत)" का उपयोग कर सकते हैं। इस तरह उपयोगकर्ता नेत्रहीन देख सकता है कि एप्लिकेशन को गेम शुरू होने तक डाउनलोड करने के लिए समय चाहिए। इसके बिना उपयोगकर्ता को किसी भी नेत्रहीन प्रतिक्रिया के बिना पूरे आवेदन के लिए इंतजार करना पड़ता है।
सैमीफॉक्स

@SammieFox ऐसा करने के अन्य (और बेहतर) तरीके हैं, सबसे विशेष रूप से <script async="true" src="...">। इन्हें भी देखें: w3bits.com/async-javascript
Ruud Helderman

जवाब खतरनाक सलाह है; बहुत सारे डेवलपर्स के नियंत्रण में होने का गलत अर्थ है। सलाह सॉफ्टवेयर के लिए कुछ अर्थ रखती है जो अब सक्रिय रूप से बनाए नहीं रखा गया है। लेकिन ऐसे सॉफ्टवेयर को मृत माना जाना चाहिए।
रूड हेलडरमैन

0

केवल परीक्षण के दौरान, यदि संभव हो तो। यह भी ध्यान दें कि अन्य विशिष्ट JSON आदि मूल्यांकनकर्ताओं की तुलना में eval () बहुत धीमा है।


0

जब तक आप यह सुनिश्चित कर सकते हैं कि कोड का स्रोत आपके या वास्तविक उपयोगकर्ता से आता है, तब तक eval () का उपयोग नहीं करने का कोई कारण नहीं है। भले ही वह उस चीज़ में हेरफेर कर सकता है जो ईवैल () फ़ंक्शन में भेजी जाती है, यह एक सुरक्षा समस्या नहीं है, क्योंकि वह वेब साइट के स्रोत कोड में हेरफेर करने में सक्षम है और इसलिए जावास्क्रिप्ट कोड को ही बदल सकता है।

तो ... जब eval () का उपयोग नहीं करना है? एवल () का उपयोग केवल तब नहीं किया जाना चाहिए जब एक मौका हो कि कोई तीसरा पक्ष इसे बदल सकता है। जैसे क्लाइंट और आपके सर्वर के बीच कनेक्शन को रोकना (लेकिन अगर वह समस्या है HTTPS का उपयोग करें)। आपको पार्सिंग कोड के लिए eval () नहीं होना चाहिए जो किसी फोरम में दूसरों द्वारा लिखा गया हो।


"जब तक आप यह सुनिश्चित कर सकते हैं कि कोड का स्रोत आपके या वास्तविक उपयोगकर्ता से आता है, तब तक eval () का उपयोग न करने का कोई कारण नहीं है।" यह मानता है कि एक एकल उपयोगकर्ता है। ओपी में वह आधार नहीं बताया गया है। जब कई उपयोगकर्ता होते हैं, तो evalएक उपयोगकर्ता से सामग्री से बना एक स्ट्रिंग से लापरवाह उस उपयोगकर्ता को दूसरे उपयोगकर्ता के ब्राउज़र में कोड निष्पादित करने की अनुमति दे सकता है।
माइक सैमुअल

@MikeSamuel, eval अन्य उपयोगकर्ता के ब्राउज़र में कोड निष्पादित कर सकता है, मैंने यह सुना है, क्या आपने यह कोशिश की है? ब्राउज़िंग के इतिहास में ऐसा कभी नहीं हुआ, क्या आप हमें एक उदाहरण दिखा सकते हैं?
आकाश काव

@AkashKava, एक स्ट्रिंग एक उपयोगकर्ता-एजेंट के साथ उत्पन्न हो सकती है, एक डेटाबेस में संग्रहीत की जा सकती है, और फिर किसी अन्य ब्राउज़र को सेवा दी जा सकती है जो evalइसे पसंद करती है। हस समय यह होता रहता है।
माइक सैमुअल

@ मायकेसमुएल डेटाबेस? कहाँ पे? कौन गलत स्ट्रिंग परोसता है? यह दोष के लिए सर्वर की ओर डेटाबेस नहीं है? सबसे पहले EVAL को खराब लिखे गए सर्वर साइड कोड के लिए दोषी नहीं ठहराया जाना चाहिए। Jsfiddle का उपयोग करें और दुनिया को एक वास्तविक विश्व उदाहरण दिखाएं जहां यह नुकसान पहुंचा सकता है।
आकाश काव

2
@ आकाशवाणी, मैं आपके प्रश्न को नहीं समझता। हम एक विशिष्ट एप्लिकेशन के बारे में बात नहीं कर रहे हैं, लेकिन उपयोग नहीं करने के कारण eval। सर्वर को दोष देने के लिए यह कैसे उपयोगी है? अगर किसी को दोषी ठहराया जाना चाहिए, तो यह हमलावर होना चाहिए। दोष के बावजूद, एक क्लाइंट जो सर्वर में बग के बावजूद XSS के लिए असुरक्षित नहीं है, वह एक क्लाइंट से बेहतर है जो कमजोर है, बाकी सभी समान हैं।
माइक सैमुअल

0

अगर यह वास्तव में आवश्यक है तो बुराई बुराई नहीं है। लेकिन मेरे द्वारा चुराए गए eval के 99.9% उपयोग की आवश्यकता नहीं है (सेटटाइमआउट सामग्री सहित)।

मेरे लिए बुराई एक प्रदर्शन या एक सुरक्षा मुद्दा भी नहीं है (ठीक है, परोक्ष रूप से यह दोनों है)। Eval के ऐसे सभी अनावश्यक उपयोग एक रखरखाव नरक में जोड़ते हैं। रिफैक्टरिंग उपकरण फेंक दिए जाते हैं। कोड की खोज कठिन है। उन evals के अप्रत्याशित प्रभाव लीजन हैं।


5
eval setTimeout के लिए आवश्यक नहीं है। आप एक फ़ंक्शन संदर्भ का भी उपयोग कर सकते हैं।
मैथ्यू क्रुमले

0

जब जावास्क्रिप्ट है eval () नहीं बुराई?

मैं हमेशा eval का उपयोग करने से हतोत्साहित करने की कोशिश कर रहा हूँ । लगभग हमेशा, एक अधिक स्वच्छ और बनाए रखने योग्य समाधान उपलब्ध है। Eval भी JSON को पार्स करने की जरूरत नहीं है । ईगल रखरखाव नरक में जोड़ता है । बिना कारण के, यह डगलस क्रॉकफोर्ड जैसे स्वामी द्वारा पर आधारित है।

लेकिन मुझे एक उदाहरण मिला जहां इसका इस्तेमाल किया जाना चाहिए :

जब आपको अभिव्यक्ति पास करने की आवश्यकता हो।

उदाहरण के लिए, मेरे पास एक फ़ंक्शन है जो google.maps.ImageMapTypeमेरे लिए एक सामान्य ऑब्जेक्ट का निर्माण करता है , लेकिन मुझे इसे नुस्खा बताने की आवश्यकता है, इसे zoomऔर coordपैरामीटर से टाइल URL का निर्माण कैसे करना चाहिए :

my_func({
    name: "OSM",
    tileURLexpr: '"http://tile.openstreetmap.org/"+b+"/"+a.x+"/"+a.y+".png"',
    ...
});

function my_func(opts)
{
    return new google.maps.ImageMapType({
        getTileUrl: function (coord, zoom) {
            var b = zoom;
            var a = coord;
            return eval(opts.tileURLexpr);
        },
        ....
    });
}

3
ऐसा लगता है कि इसे फिर से सक्रिय किया जा सकता है ताकि eval () आवश्यक नहीं है - टाइललक्लेक्स बस एक टेम्पलेट है ताकि प्रतिस्थापन के कुछ विवेकपूर्ण उपयोग () काम करेंगे। फिर भी, यह मुझे एक उदाहरण की याद दिलाता है जो मेरे मन में था जब मैंने प्रश्न प्रस्तुत किया था, जो कि स्प्रेडशीट कार्यक्षमता के समान, एक उपयोगकर्ता को गणितीय सूत्र निर्दिष्ट करने की अनुमति देने के लिए था। बेशक, मैंने उस समय का उल्लेख नहीं किया क्योंकि मैं उत्तरों को प्रभावित नहीं करना चाहता था!
रिचर्ड टर्नर

8
tileURL: function (zoom, coord) { return 'http://tile.openstreetmap.org/' + b + '/' + a.x + '/' + a.y + '.png'; },
केसी चू

0

उपयोग करने का मेरा उदाहरण eval: आयात

यह आमतौर पर कैसे किया जाता है।

var components = require('components');
var Button = components.Button;
var ComboBox = components.ComboBox;
var CheckBox = components.CheckBox;
...
// That quickly gets very boring

लेकिन evalऔर एक छोटे सहायक समारोह की मदद से यह एक बहुत बेहतर लग रहा है:

var components = require('components');
eval(importable('components', 'Button', 'ComboBox', 'CheckBox', ...));

importable ऐसा लग सकता है (यह संस्करण ठोस सदस्यों को आयात करने का समर्थन नहीं करता है)।

function importable(path) {
    var name;
    var pkg = eval(path);
    var result = '\n';

    for (name in pkg) {
        result += 'if (name !== undefined) throw "import error: name already exists";\n'.replace(/name/g, name);
    }

    for (name in pkg) {
        result += 'var name = path.name;\n'.replace(/name/g, name).replace('path', path);
    }
    return result;
}

2
विचार के लिए +1, लेकिन आप एक बग यहाँ है: .replace(/name/g, name).replace('path', path)। यदि nameस्ट्रिंग होती है "path"तो आपको आश्चर्य हो सकता है।
wberry

1
प्रत्येक गुण के लिए एक चर घोषित componentsकरना एक संभावित कोड गंध है; आपके कोड को फिर से भरने से 'समस्या' पूरी तरह समाप्त हो सकती है। आपका वर्तमान समाधान सिंटैक्टिक शुगर है। यदि आप ऐसा करने पर जोर देते हैं, तो मैं आपके स्वयं के पूर्वप्रक्रम लिखने की सलाह दूंगा, जिसे तैनाती से पहले निष्पादित किया जाना चाहिए। कि evalउत्पादन कोड से दूर रखना चाहिए ।
रूड हेलडरमैन

0

बुराई बुराई नहीं है, सिर्फ दुरुपयोग है।

यदि आपने इसमें जाने वाला कोड बनाया है या इस पर भरोसा कर सकते हैं, तो यह ठीक है। लोग इस बारे में बात करते रहते हैं कि उपयोगकर्ता का डेटा किस तरह से मायने नहीं रखता। अच्छी तरह से ~

यदि उपयोगकर्ता इनपुट है जो सर्वर पर जाता है, तो क्लाइंट में वापस आता है, और उस कोड का उपयोग निष्कासित किए बिना किया जा रहा है। बधाई हो, आपने उपयोगकर्ता डेटा के लिए पैंडोरा का बॉक्स खोला है जिसे भी भेजा जाएगा।

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

सिर्फ यह समझें कि क्या आप eval का उपयोग कर रहे हैं। जनरेटिंग कोड वास्तव में आदर्श नहीं है, जब आप बस उस तरह का काम करने के लिए तरीके बना सकते हैं, वस्तुओं का उपयोग कर सकते हैं, या पसंद कर सकते हैं।

अब eval का उपयोग करने का एक अच्छा उदाहरण है। आपका सर्वर आपके द्वारा बनाई गई स्वैगर फ़ाइल पढ़ रहा है। URL पैरामेट्स के कई प्रारूप में बनाए गए हैं {myParam}। इसलिए आप URL पढ़ना चाहते हैं और फिर उन्हें जटिल प्रतिस्थापन किए बिना टेम्पलेट स्ट्रिंग में परिवर्तित कर सकते हैं क्योंकि आपके पास कई समापन बिंदु हैं। तो आप ऐसा कुछ कर सकते हैं। ध्यान दें यह एक बहुत ही सरल उदाहरण है।

const params = { id: 5 };

const route = '/api/user/{id}';
route.replace(/{/g, '${params.');

// use eval(route); to do something

-1

कोड पीढ़ी। मैंने हाल ही में हाइपरबर्स नामक एक लाइब्रेरी लिखी है जो वर्चुअल-डोम और हैंडलबार्स के बीच की खाई को पाटती है । यह एक हैंडलबार टेम्पलेट को पार्स करके और इसे हाइपरस्क्रिप्ट में परिवर्तित करके करता है । हाइपरस्क्रिप्ट पहले एक स्ट्रिंग के रूप में उत्पन्न होता है और इसे वापस करने से पहले, eval()इसे निष्पादन योग्य कोड में बदलना है। मैंने eval()इस विशेष स्थिति में बुराई के ठीक विपरीत पाया है।

मूल रूप से

<div>
    {{#each names}}
        <span>{{this}}</span>
    {{/each}}
</div>

इसके लिए

(function (state) {
    var Runtime = Hyperbars.Runtime;
    var context = state;
    return h('div', {}, [Runtime.each(context['names'], context, function (context, parent, options) {
        return [h('span', {}, [options['@index'], context])]
    })])
}.bind({}))

प्रदर्शन eval()इस तरह की स्थिति में भी कोई समस्या नहीं है क्योंकि आपको केवल एक बार उत्पन्न स्ट्रिंग की व्याख्या करने की आवश्यकता है और फिर कई बार निष्पादन योग्य आउटपुट का पुन: उपयोग करें।

आप देख सकते हैं कि यदि आप यहां उत्सुक हैं तो कोड पीढ़ी कैसे प्राप्त की गई थी ।


"हाइपरस्क्रिप्ट को पहले एक स्ट्रिंग के रूप में उत्पन्न किया जाता है (...)" निर्माण चरण में सभी कोड पीढ़ी करने के लिए अधिक समझ में आता है, परिणामी हाइपरस्क्रिप्ट कोड को एक अलग निष्पादन योग्य (.js) फ़ाइल में लिखें, फिर उस फ़ाइल को परीक्षण के लिए तैनात करें। उत्पादन। मुझे आपके द्वारा कोड जनरेशन का उपयोग करने का तरीका पसंद है। यह सिर्फ evalएक संकेत है कि कुछ जिम्मेदारी जो संकलित समय में है, रनटाइम में चली गई है।
रूड हेलडरमैन

-1

मेरा मानना ​​है कि क्लाइंट-साइड वेब एप्लिकेशन और सुरक्षित के लिए eval एक बहुत शक्तिशाली कार्य है ... जावास्क्रिप्ट के रूप में सुरक्षित है, जो नहीं हैं। :-) सुरक्षा मुद्दे अनिवार्य रूप से सर्वर-साइड समस्या हैं क्योंकि, अब, फायरबग जैसे उपकरण के साथ, आप किसी भी जावास्क्रिप्ट एप्लिकेशन पर हमला कर सकते हैं।


1
evalXSS हमलों के खिलाफ सुरक्षित होने की जरूरत का उपयोग , जो हमेशा सही होने के लिए आसान नहीं है।
बेंजामिन

-1

जब आपके पास मैक्रोज़ न हों तो कोड जनरेशन के लिए इवल उपयोगी है।

(बेवकूफ) उदाहरण के लिए, यदि आप एक ब्रेनफैक कंपाइलर लिख रहे हैं, तो आप संभवतः एक फ़ंक्शन का निर्माण करना चाहेंगे जो एक स्ट्रिंग के रूप में निर्देशों का अनुक्रम करता है, और एक फ़ंक्शन को वापस करने के लिए इसे eval करता है।


या तो आप एक संकलक लिखते हैं (जो उत्पन्न होने वाले कोड को निष्पादित करने के बजाय बचाता है) या आप एक दुभाषिया लिखते हैं (जहां प्रत्येक निर्देश में पूर्व-संकलित कार्यान्वयन है)। न ही उपयोग के लिए मामला है eval
रूड हेलडरमैन

यदि आप जावास्क्रिप्ट कोड उत्पन्न करते हैं और इसे तुरंत निष्पादित करना चाहते हैं (चलो प्रत्यक्ष व्याख्या पर प्रदर्शन लाभ के लिए कहते हैं), जो कि निष्कासन के लिए उपयोग मामला होगा।
एरिक हैलिवेज़ ज़ूल

अच्छी बात; मैंने ब्लॉकली के बारे में इस लेख में एक उदाहरण देखा । मैं हैरान हूं कि Google अनुशंसा करता है eval, जब वैकल्पिक ( फ़ंक्शन ) दोनों तेजी से होता है ( जैसा कि एमडीएन में समझाया गया है ) और अधिक विश्वसनीय (जेनरेट किए गए कोड और समान वेबपेज पर अन्य 'सहायक' कोड के बीच बेहतर अलगाव से अप्रत्याशित बग को रोकता है)।
रूड हेलडरमैन

-5

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


4
आँख बंद करके eval, esp का उपयोग न करें । जब JSON डेटा किसी तृतीय-पक्ष स्रोत से प्राप्त कर रहा हो। गुणों पर उद्धरण के बिना JSON.Stringify देखें ? "JSON बिना उद्धृत कुंजी नामों" को पार्स करने के लिए सही दृष्टिकोण के लिए।
रोब डब्ल्यू

2
यदि यह संपत्ति के नामों के आसपास दोहरे उद्धरण चिह्नों का उपयोग नहीं करता है, तो यह एक वस्तु शाब्दिक का एक स्ट्रिंग प्रतिनिधित्व हो सकता है, लेकिन यह JSON नहीं है । JSON एक के रूप में संपत्ति के नाम को stringपरिभाषित करता है और शून्य या अधिक यूनिकोड वर्णों के अनुक्रम केstring रूप में परिभाषित करता है , बैकस्लैश बच का उपयोग करके दोहरे उद्धरणों में लिपटे हुए है।
बेकार संहिता

निकोलस ज़कस का लेख देखें - "eval () बुराई नहीं है, बस गलत समझे" nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood
vitmalina

@vitmalina Zakas के लेख से: "यह खतरनाक हो सकता है यदि आप उपयोगकर्ता इनपुट ले रहे हैं और इसे eval () के माध्यम से चला रहे हैं। हालांकि, यदि आपका इनपुट उपयोगकर्ता से नहीं है, तो क्या कोई वास्तविक खतरा है?" ठीक यही समस्या है। एक बार जब आपका कोड 'हैलो वर्ल्ड' के अनुपात से आगे बढ़ता है, तो यह साबित करना असंभव हो जाता है कि आप उपयोगकर्ता इनपुट को लीक नहीं कर रहे हैं eval। किसी भी गंभीर मल्टी-टेनेंट वेब एप्लिकेशन में, दर्जनों डेवलपर्स एक ही कोड बेस पर काम कर रहे हैं, यह अस्वीकार्य है।
Ruud Helderman
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.