जावास्क्रिप्ट एवल फीचर के "अनुचित उपयोग" का गठन क्या है? [बन्द है]


13

एवल एक कुख्यात विवादास्पद भाषा सुविधा है। डगलस क्रॉकफोर्ड फ्लैट आउट इसे अस्वीकार कर देता है। मैं सोच रहा हूं कि ईवल किस विशिष्ट जोखिम के बारे में बताता है। के अनुसार इस सवाल है, Improper use of eval opens up your code for injection attacks

एवल कमांड के कुछ अनुचित उपयोग क्या हैं, और वे किस सुरक्षा छेद को खोलते हैं?

जवाबों:


31

जब मैं JScript इंजन को लागू कर रहा था, तो मैंने EVAL IS EVIL शर्ट को प्रिंट करने की वकालत की थी, लेकिन दुख की बात यह है कि हम इसके आसपास कभी नहीं पहुंचे।

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

इस नस में कुछ और विचारों के लिए इस विषय पर 2003 से मेरे लेख देखें:

सामान्य बुराई:

http://blogs.msdn.com/b/ericlippert/archive/2003/11/01/53329.aspx

इंजेक्शन हमले की बुराई:

http://blogs.msdn.com/b/ericlippert/archive/2003/11/04/53335.aspx


evalजिस तरह से JSPacker जैसे अनुप्रयोगों के लिए कोड की बड़ी मात्रा पर आपके विचार क्या हैं ? JSPacker + gzip आमतौर पर अपने आप ही समाधान की तुलना में छोटे फ़ाइल आकारों में परिणाम करता है, लेकिन जैसा कि आप ठीक से इंगित करते हैं कि यह अनिवार्य रूप से कोड के एक ही टुकड़े पर दो बार एक संकलक को फायरिंग कर रहा है, साथ ही स्ट्रिंग प्रतिस्थापन करने के लिए कुछ ओवरहेड।
मैथ्यू शार्ले

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

मैं जवाब मैं देखा था से एक इच्छा या तो यहाँ या इतने पर ही कहा गया है | क्या आपके दूसरी कड़ी कहता है: कि eval()है नहीं ग्राहक (ब्राउज़र) कोड पर एक सुरक्षा जोखिम।
sq33G

4

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

एक तुच्छ और बेकार उदाहरण के रूप में, एक सरल जावास्क्रिप्ट कैलकुलेटर:

textbox1.value = eval(textbox2.value);

एक सही उपयोग के उदाहरण जावास्क्रिप्ट पैकर्स में से कुछ हैं जो सामान्य शब्दों को बाहर निकालकर शॉर्ट 1-2 वर्ण प्रतिस्थापन के साथ जावास्क्रिप्ट को संपीड़ित करते हैं। पैकर फिर उत्पन्न शब्दकोश के आधार पर स्ट्रिंग प्रतिस्थापन कोड के साथ यह सब आउटपुट करता है फिर परिणाम निकालता है।


1

वहाँ कुछ चीजें एक eval की तरह समारोह के बिना जे एस में करने के लिए असंभव है कि कर रहे हैं ( eval, Function, और शायद अधिक)।

applyउदाहरण के लिए लें । साधारण फ़ंक्शन कॉल पर इसका उपयोग करते समय उपयोग करना आसान है:

foo.apply(null, [a, b, c])

लेकिन आप उन वस्तुओं के लिए यह कैसे करेंगे जो आप नए वाक्य रचना के माध्यम से बना रहे हैं?

new Foo.apply(null, [a, b, c]) काम नहीं करता है, और न ही समान रूप नहीं है।

लेकिन आप इस सीमा के आसपास काम कर सकते हैं evalया Function(मैं Functionइस उदाहरण में उपयोग करता हूं ):

Function.prototype.New = (function () {
    var fs = [];
    return function () {
        var f = fs[arguments.length];
        if (f) {
            return f.apply(this, arguments);
        }
        var argStrs = [];
        for (var i = 0; i < arguments.length; ++i) {
            argStrs.push("a[" + i + "]");
        }
        f = new Function("var a=arguments;return new this(" + argStrs.join() + ");");
        if (arguments.length < 100) {
            fs[arguments.length] = f;
        }
        return f.apply(this, arguments);
    };
}) ();

उदाहरण:

Foo.New.apply(null, [a, b, c]);

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


2
यह सच है, लेकिन ओपी का सवाल था कि " एवल कमांड के कुछ अनुचित उपयोग क्या हैं, और वे किस सुरक्षा छेद को खोलते हैं? ", " क्या एक अच्छा उपयोग नहीं है eval()? "
रॉस पैटरसन

1
@RossPatterson: लगता है कि मैं ज्यादातर सवाल शीर्षक haha ​​को देखा।
थॉमस एडिंग

फिर भी, एक खराब भाषा सुविधा के लिए एक अच्छा उपयोग खोजने के लिए +1 :-)
रॉस पैटरसन

1

मेरी ओर से कुछ प्रत्यक्ष उत्तर डेवलपर-आधारित एपीआई-परीक्षण क्षेत्र विकसित कर रहा था। हमने एक पृष्ठ पर एक पाठ क्षेत्र, और एक रन बटन दिया। पृष्ठ का केंद्रीय बिंदु उनके लिए हमारे आइफ्रेम-संवाद करने वाले एपीआई के खिलाफ जावास्क्रिप्ट में चीजों को आज़माने में सक्षम होना था जो स्थानीय वातावरण में ऐसा करना आसान नहीं था।

उस मामले में जो कुछ भी दुर्भावनापूर्ण किया जा सकता था, वह डेवलपर द्वारा उनके F12 टूल को खोलने के लिए भी किया जा सकता था।


0

मैं इस बात से सहमत हूं कि इसका उपयोग बहुत कम ही किया जाना चाहिए, लेकिन मैंने इसके लिए एक शक्तिशाली उपयोग मामला पाया है eval

फ़ायरफ़ॉक्स में एक प्रायोगिक नई सुविधा है जिसे asm.js कहा जाता है, जिसके साथ मैं काम कर रहा हूं। यह जावास्क्रिप्ट भाषा के एक सीमित उपसमूह को देशी कोड में संकलित करने की अनुमति देता है। हां, यह बहुत भयानक है, लेकिन इसकी सीमाएं हैं। आप जावास्क्रिप्ट के सीमित उपसमुच्चय के बारे में सोच सकते हैं कि जावास्क्रिप्ट में सी-जैसी भाषा अंतर्निहित है। यह वास्तव में मनुष्यों द्वारा पढ़ा या लिखा जाने वाला नहीं है।

जावास्क्रिप्ट का यह सीमित सबसेट मुझे एक बार संकलित कोड में अपने रनटाइम-जनरेट किए गए कोड को इंजेक्ट करने की अनुमति नहीं देता है।

मैंने कुछ कोड लिखे हैं जो एक उपयोगकर्ता को परिचित अंकन, एक गणितीय अभिव्यक्ति में लिखने की अनुमति देता है, और क्या यह मक्खी पर asm.js कोड में परिवर्तित हो गया है। जब तक मैं सर्वर साइड पर संसाधित कोड नहीं चाहता था (जो मैं नहीं करता), evalएकमात्र उपकरण है जो मुझे वास्तविक समय में ब्राउज़र द्वारा परिणामी कोड को संसाधित करने की अनुमति देता है।


0

जैसा कि दूसरों द्वारा बताया गया है, जब सबसे महत्वपूर्ण बात evalयह है कि इसे सुरक्षित रखना है। उसके लिए, आप पूरी तरह से तर्क की जाँच करना चाहते हैं, और eval'एड कोड को सरल बनाए रखें क्योंकि आमतौर पर रन-टाइम जनरेट किए गए कोड को बनाए रखना और सुरक्षित करना बहुत कठिन होता है।

कहा जा रहा है कि, मुझे evalदो तरह की चीजों का उपयोग करने में मज़ा आता है (भले ही शायद बेहतर, कम बुराई-ईश विकल्प हो)

  1. चूंकि eval"स्पष्ट रूप से कैशिंग कोड" का एक तरीका है, इसका उपयोग प्रदर्शन को बेहतर बनाने के लिए किया जा सकता है। ध्यान दें कि ऑप्टिमाइज़र हमेशा बेहतर हो रहे हैं, लेकिन इस बात की कोई गारंटी नहीं है कि वे आपके लिए क्या कर सकते हैं। कोड में चीजों को स्पष्ट करके, आप वास्तव में आशावादी को बेहतर निर्णय लेने में मदद कर सकते हैं।
  2. इसका उपयोग प्रकार-सुरक्षा के बुनियादी रूपों को वितरित करने के लिए भी किया जा सकता है, साथ ही साथ अन्य भाषा सुविधाएँ जिन्हें जेएस की कमी है, बिना खराब प्रदर्शन के।

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

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


-3

मेरे पास एक ऐसी स्थिति है जहां eval जाने का रास्ता दिखता है, एक स्ट्रिंग का मूल्यांकन करता है और एक मौजूदा चर को लौटाता है जिसका नाम स्ट्रिंग के समान है।

मेरे पास कई टेबल हैं: table1ResultsTable, table2ResultsTable, tableNResultsTable। मेरे पास एक ही नाम के साथ वैरिएबल सेट हैं, जो कि jQuery डेटाेबल ऑब्जेक्ट हैं। मैं तालिकाओं को स्थापित करने और उन पर jQuery डेटा योग्य कार्यों को कॉल करने के लिए इनका उपयोग करता हूं।

प्रत्येक तालिका में कक्षा = "परिणाम" निर्दिष्ट है। अब, जब तालिका पर क्लिक किया जाता है, तो मुझे चर प्राप्त करने की आवश्यकता होती है। मैं यह कर रही हूँ:

$('resultsTable).on('click', 'td', function(event) {
    var cResultsTable = eval(event.target.parentElement.parentElement.parentElement.id);
    [etc]
});

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


1
आपको eval की आवश्यकता क्यों है? आईडी एक सादा स्ट्रिंग होना चाहिए, कोड नहीं। किसी भी तरह, event.target.parentElement.parentElement.parentElementभयावह है। इसके अलावा, मुझे "संदर्भ त्रुटि: [आईडी] परिभाषित नहीं है" त्रुटि उत्पन्न करने के लिए eval कॉल की उम्मीद है, जब तक कि आप जानबूझकर मूल्यांकन योग्य आईडी का उपयोग नहीं कर रहे हैं (जो टूटी हुई है, गलत है, और आपके समाप्त होने पर अजीब चीजें हो सकती हैं। डुप्लिकेट आईडी बनाना)।
ब्रायन

शायद मैं खुद को स्पष्ट नहीं कर रहा हूं। आईडी एक सादे तार है। यह उस तालिका की आईडी है जिसे क्लिक किया गया है। मेरे पास एक ऑब्जेक्ट वैरिएबल (jQuery डेटाटेबल के साथ सेट) विधि, एक ही तालिका को आईडी के समान नाम के साथ संदर्भित करता है। मैं उस चर को प्राप्त करने की कोशिश कर रहा हूं, जब उसके कार्यों तक पहुंचने के लिए (वास्तव में, "रो_सेलेक्टेड" वर्ग को चयनित पंक्ति में जोड़ने के लिए), जब तालिका पर क्लिक किया जाता है। जब से मैंने यह लिखा है, मैं एक सुधार के साथ आया हूं, हालांकि। मैं सिर्फ सभी ऑब्जेक्ट संदर्भों को एक सरणी में रखता हूं, तत्वों को आईडी के समान नाम देता हूं, और ऑब्जेक्ट स्ट्रिंग को प्राप्त करने के लिए आईडी स्ट्रिंग को प्लग करता हूं।
BobRodes 19'13

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

1
शायद मैं खुद को स्पष्ट नहीं कर रहा हूं। यदि आप एक सादे (यानी, गैर-जेएस) स्ट्रिंग पर eval कहते हैं, तो आप एक अपवाद फेंक देंगे। इसलिए, आपके उपयोग का कोई मतलब नहीं है। यदि आप आईडी के समान नाम के साथ ऑब्जेक्ट चर उत्पन्न कर रहे हैं, तो आपका कोड काम करेगा ... लेकिन मुझे टूटे हुए के रूप में। मैं इसके बजाय चर का उपयोग करके बनाऊंगा document.getElementById(ID).MySpecialProperty = MYSPECIALPROPERTYVALUE(यह कहने के लिए कि यह बहुत अच्छा नहीं है, लेकिन यह eval से बेहतर है)। जैसा कि एरिक लिपर्ट बताते हैं, "JScript में हर ऑब्जेक्ट पहले से ही लुकअप टेबल है।"
ब्रायन

ठीक है, तो आप तत्व संदर्भ में एक संपत्ति जोड़ने और इसे datatable वस्तु संदर्भ में सेट करने के लिए कह रहे हैं? यह मेरे लिए भी तंग लगता है।
BobRodes 14'13
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.