जब एक स्ट्रिंग नहीं है तो क्या SQL क्वेरी को पैरामीटर नहीं करना सुरक्षित है?


113

SQL इंजेक्शन के संदर्भ में , मैं पूरी तरह से एक stringपैरामीटर को मानकीकृत करने की आवश्यकता समझता हूं ; यह पुस्तक की सबसे पुरानी चालों में से एक है। लेकिन जब यह करने के लिए उचित हो सकता है नहीं एक parameterize SqlCommand? क्या किसी भी डेटा प्रकार को "सुरक्षित" माना जाता है जो पैरामीटर नहीं करता है?

उदाहरण के लिए: मैं अपने आप को SQL के किसी विशेषज्ञ के पास कहीं भी नहीं मानता , लेकिन मैं ऐसे किसी भी मामले के बारे में नहीं सोच सकता, जहाँ यह SQL इंजेक्शन के लिए संभावित रूप से असुरक्षित हो सकता है boolया intइसे सही तरीके से स्वीकार कर सकता है ।

क्या मेरी धारणा सही है, या वह संभवतः मेरे कार्यक्रम में एक बड़ी सुरक्षा भेद्यता छोड़ सकती है?

स्पष्टीकरण के लिए, इस प्रश्न को टैग किया गया है जो एक जोरदार टाइप की गई भाषा है; जब मैं कहता हूं "पैरामीटर," कुछ ऐसा सोचें public int Query(int id)


14
यदि आप मापदंडों का उपयोग नहीं करते हैं, तो आपको कैश्ड क्वेरी योजनाओं का लाभ नहीं मिलेगा, आपके द्वारा प्रदान किए जाने वाले इनपुट के हर नए संयोजन के लिए एक अलग क्वेरी प्लान बनाने की आवश्यकता होगी।
स्कॉट चैंबरलेन

5
@MatthewWhited आपको कैसे पता चलेगा कि इसमें कम समय लगता है? यह स्थिति वर्तमान डेवलपर और पिछले डेवलपर से कुछ परियोजनाओं में सभी जगह होती है। यदि यह वास्तव में सुरक्षा में सुधार करता है, तो कृपया उत्तर दें। स्पष्टीकरण के लिए, मैं सहमत हूं कि स्पष्ट रूप से इसे बेहतर बनाना है। लेकिन यह वास्तव में मेरा सवाल नहीं है।
johnnyRose 2

7
पैरामीटर प्रश्नों को मुख्य रूप से प्रदर्शन और अनुकूलन के लिए उपयोग किया जाता है। एसक्यूएल इंजेक्शन की रोकथाम एक साइड इफेक्ट है।
सलमान ए

13
मुझे लगता है कि ओपी ने एक वैध प्रश्न पूछा है। वह संभावित जोखिम को ठीक करने की लागत / लाभ का मूल्यांकन करने की कोशिश कर रहा है। उस जोखिम की क्षमता के साथ यह समीकरण बदल जाता है। यदि शून्य जोखिम है, तो मैं इसे नहीं करूंगा। उन्होंने क्षमता के बारे में एक तकनीकी प्रश्न पूछा है, न कि व्यक्तिपरक निर्णय के लिए कि आप उसके समय के लायक समझते हैं। ओपी ही एकमात्र है जो उस कॉल को कर सकता है।
सर स्वियर्स-ए-लॉट

10
खुद को समझाने के लिए: मैं एक डीबीए हूं। मैं सर्वश्रेष्ठ अभ्यास की सराहना और सम्मान करता हूं, और एक आदर्श दुनिया में सभी कोड सही होंगे। दुःख की बात यह है कि जिस दुनिया में मैं काम करता हूं, मेरे पास उसे हल करने के लिए जितना समय है, उससे ज्यादा समस्याएं हैं। IMO रीराइटिंग कोड जो पहले से ही काम करता है, सुरक्षित है और स्वीकार्य स्तर पर लग्जरी की तरह काम करता है। (जो मैं बर्दाश्त नहीं कर सकता)
सर स्वैर्स-ए-लॉट

जवाबों:


101

मुझे लगता है कि यह सुरक्षित है ... तकनीकी रूप से , लेकिन यह एक भयानक आदत है। क्या आप वास्तव में इस तरह के प्रश्न लिखना चाहते हैं?

var sqlCommand = new SqlCommand("SELECT * FROM People WHERE IsAlive = " + isAlive + 
" AND FirstName = @firstName");

sqlCommand.Parameters.AddWithValue("firstName", "Rob");

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

इसलिए, हमने EmployeeNumber के प्रकार को इससे बदल दिया intहै string, लेकिन हमारे sql क्वेरी को अपडेट करना भूल गया है। उफ़।


24
क्या हम AddWithValue पहले से ही उपयोग करना बंद कर सकते हैं ? blogs.msmvps.com/jcoehoorn/blog/2014/05/12/…
RemarkLima

5
@REDIALima जब आप डायनामिकली कोड जनरेट कर रहे हैं तो इसका क्या उपाय है जो मानों को मैप करता है? ब्लॉग पोस्ट उस परिदृश्य को संबोधित करने में विफल रहता है। हां, यह ज्ञात होने पर SQL प्रकार सेट करने के लिए एक एकल पंक्ति है , लेकिन जब यह नहीं है, तो आपको एक समस्या है (या आपको उस जानकारी के साथ मॉडल को एनोटेट करने का सहारा लेना होगा)।
कैस्परऑने

1
तब AddWithValueतक आप तब तक अटके रहेंगे जब तक कि आपके पास स्टेटमेंट के डायनामिक बिल्डिंग के हिस्से के रूप में डेटाबेस प्रकारों की मैपिंग न हो। मुझे लगता है कि आपके पास लक्ष्य स्तंभों की एक सूची है, और शब्दकोश के भाग के रूप में, यदि आप चाहें तो आपके पास प्रकार हो सकते हैं। अन्यथा, बस प्रदर्शन हिट ले लो। अंत में, मुझे पता है कि यह सिर्फ अच्छी जानकारी है।
रिमार्कलिमा

8
@REDIALima बिंदु "क्या हम AddWithValueपहले से ही उपयोग करना बंद कर सकते हैं ?" वास्तव में होना चाहिए "यदि आप प्रकार जानते हैं, तो आपको उपयोग करने से बचना चाहिए AddWithValue
casperOne

2
अरे, दूत को गोली मत मारो, मैंने इसे नहीं लिखा;; लेकिन बिंदु बना हुआ है, और यदि शुरू से आपके डिजाइनों में बनाया गया है, तो कोई कारण नहीं है कि आपको प्रकार पता नहीं होना चाहिए। सबसे अच्छा अभ्यास और वह सब जाज :-)
रेमर्कलिमा

65

एक कंप्यूटर आप (एक वेब सर्वर की तरह) पर नियंत्रण पर एक जोरदार टाइप मंच का उपयोग करते समय, आप केवल के साथ प्रश्नों के लिए कोड इंजेक्शन रोका जा सकता है bool, DateTimeया int(और अन्य संख्यात्मक) मान। चिंता की बात यह है कि हर क्वेरी को फिर से संकलित करने के लिए एसक्यूएल सर्वर को मजबूर करने के कारण प्रदर्शन के मुद्दे हैं, और इसे किस आवृत्ति (जो कैश प्रबंधन को नुकसान पहुंचाता है) के साथ प्रश्नों को चलाने के अच्छे आंकड़े प्राप्त करने से रोकते हैं।

लेकिन वह "आपके द्वारा नियंत्रित कंप्यूटर पर" भाग महत्वपूर्ण है, क्योंकि अन्यथा एक उपयोगकर्ता सिस्टम द्वारा उपयोग किए जाने वाले व्यवहार को उन मूल्यों से तार उत्पन्न करने के लिए मनमाना पाठ शामिल करने के लिए बदल सकता है।

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

वास्तव में, इन मूल्यों के लिए क्वेरी मापदंडों का उपयोग नहीं करने का कोई अच्छा कारण नहीं है। यह इस बारे में जाने का सही तरीका है। आगे और हार्ड-कोड मान को sql string में डालें जब वे वास्तव में स्थिर होते हैं, लेकिन अन्यथा, बस एक पैरामीटर का उपयोग क्यों नहीं करते हैं? ऐसा नहीं है कि यह कठिन है।

अंततः, मैं इसे बग नहीं कहूंगा , प्रति se, लेकिन मैं इसे एक गंध कहूंगा : कुछ ऐसा जो अपने आप में बग से कम पड़ता है, लेकिन एक मजबूत संकेत है कि कीड़े पास हैं, या अंततः होंगे। अच्छा कोड गंध छोड़ने से बचता है, और कोई भी अच्छा स्थैतिक विश्लेषण उपकरण इसे चिह्नित करेगा।

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


1
यह निश्चित रूप से इसे मानकीकृत करने की चुनौती नहीं है। मेरा प्रश्न इसलिए उठा क्योंकि एक सहकर्मी ने पूर्णांक मानों को समेटते हुए प्रश्नों का एक समूह लिखा था, और मैं सोच रहा था कि क्या यह उन सभी के माध्यम से जाने और तय करने के लिए मेरे समय की बर्बादी थी।
जॉनीरोज

2
मुझे लगता है कि सवाल "क्या यह एक बग है" क्या मेरा सवाल उबलता है।
जॉनीरोज 2

7
यह एक "गंध" है: कुछ ऐसा जो अपने आप बग से कम हो जाता है, लेकिन इंगित करता है कि कीड़े पास होने की संभावना है। अच्छा कोड बदबू को खत्म करने की कोशिश करता है। कोई भी अच्छा स्थैतिक विश्लेषण उपकरण निश्चित रूप से इसे चिह्नित करेगा।
जोएल कोएहॉर्न

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

1
यह सिर्फ गलत है। उदाहरण के लिए मेरा जवाब देखें कि आप अभी भी कैसे SQL इंजेक्शन बना सकते हैं DateTimeयाint
Kaspars Ozols

53

कुछ मामलों में, स्ट्रिंग मानों के अलावा गैर-पैराट्राइज्ड (कॉन्केनेटेड) चर के साथ एसक्यूएल इंजेक्शन हमला करना संभव है - जॉन द्वारा इस लेख को देखें: http://codeblog.jonskeet.uk/2014/08/08/the-bobbyables -कल्चर /

बात यह है कि जब ToStringबुलाया जाता है, तो कुछ कस्टम कल्चर प्रदाता गैर-स्ट्रिंग पैरामीटर को अपने स्ट्रिंग प्रतिनिधित्व में बदल सकते हैं जो क्वेरी में कुछ SQL को इंजेक्ट करता है।


14
मुझे लगता है कि यह एकमात्र ऐसा पद है जो प्रश्न का उत्तर देता है, जो अनिवार्य रूप से है "इंजेक्शन intएस के साथ भी कैसे संभव हो सकता है ?"
आर्टुरो टॉरेस सेंचेज

3
यद्यपि यदि आप कस्टम कोड को इंजेक्ट करने की स्थिति में हैं जैसे कि booby के CultureInfoकारण यह जानना मुश्किल है कि आपको SQL इंजेक्शन की आवश्यकता क्यों है।
मार्टिन स्मिथ

प्लस 1, एकमात्र जवाब जो वास्तव में सवाल का जवाब देता है
ken2k

@MartinSmith: मेरे उत्तर को देखें जो बाहर से CultureInfo को बदलने का एक संभव तरीका दिखाता है।
user1027167 14

यदि कोई व्यक्ति आवेदन में ऐसा कोड लिख सकता है, तो उसे SQL इंजेक्शन की आवश्यकता क्यों है?
रेजा अगेई

51

यह गैर-स्ट्रिंग प्रकारों के लिए भी सुरक्षित नहीं हैहमेशा मापदंडों का उपयोग करें। अवधि।

निम्नलिखित कोड उदाहरण पर विचार करें:

var utcNow = DateTime.UtcNow;
var sqlCommand = new SqlCommand("SELECT * FROM People WHERE created_on <= '" + utcNow + "'");

पहली नज़र में कोड सुरक्षित दिखता है, लेकिन अगर आप विंडोज रीजनल सेटिंग्स में कुछ बदलाव करते हैं और शॉर्ट डेट फॉर्मेट में इंजेक्शन जोड़ते हैं तो सब कुछ बदल जाता है:

डाइमटाइम इंजेक्शन

अब परिणामस्वरूप कमांड टेक्स्ट इस तरह दिखता है:

SELECT * FROM People WHERE created_on <= '26.09.2015' OR '1'<>' 21:21:43'

intटाइप के लिए ऐसा ही किया जा सकता है क्योंकि उपयोगकर्ता कस्टम नेगेटिव साइन को परिभाषित कर सकता है जिसे आसानी से SQL इंजेक्शन में बदला जा सकता है।

कोई यह तर्क दे सकता है कि वर्तमान संस्कृति के बजाय अपरिवर्तनीय संस्कृति का उपयोग किया जाना चाहिए, लेकिन मैंने कई बार इस तरह के स्ट्रिंग संघनन देखे हैं और जब उपयोग करने वाली वस्तुओं के साथ तार को मिलाते हैं तो याद करना काफी आसान है +


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

5
यह सबसे अच्छा जवाब है, यह एक तरह से दिखाता है कि ओपी चिंता को मान्य करता है यह एक बग / सुरक्षा दोष है। उदाहरण के लिए एसक्यूएल में डेटाेटाइम को अलग करके प्रदर्शन और भविष्य का प्रमाण देना महज एक गंध या तकनीकी ऋण नहीं है । @RezaAghaei प्रश्न में सर्वर-साइड का कभी उल्लेख नहीं किया गया है, यह SQLExpress के साथ एक विंडोज ऐप हो सकता है - या तो इस सवाल का मानदंड नहीं है। कोई भी कह सकता है, लेकिन इस उत्कृष्ट उत्तर को पुन: प्रस्तुत करने के लिए सर्वर सेटिंग्स तक कौन पहुंच सकता है, जैसे कोई भी साझा सर्वर होस्टिंग या वाई 2 के बग के बारे में क्या कह सकता है। मैं आपसे सहमत हूँ कि सर्वर बंद है - इसका कोई शर्त नहीं है।
जेरेमी थॉम्पसन

2
क्या आप एक उदाहरण प्रदान कर सकते हैं कि आप किस intप्रकार के बारे में कह रहे थे ?
जॉनीरोज

1
मुझे पता है कि आपको यह उत्तर दिए हुए कुछ सप्ताह हो गए हैं, लेकिन क्या आपके लिए अपनी पोस्ट को संपादित करना और एक उदाहरण जोड़ना संभव होगा कि आप एक कस्टम नेगेटिव साइन को कैसे परिभाषित कर सकते हैं?
जॉनी

23

"तालिका 1 का चयन करें * कहां से =" + intVariable.ToString ()


सुरक्षा
यह ठीक है।
हमलावर आपके टाइप किए गए इंट वैरिएबल में कुछ भी इंजेक्ट नहीं कर सकते हैं।

प्रदर्शन
ठीक नहीं है।

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

कोडिंग स्टाइल
खराब अभ्यास।

  • पैरामीटर अधिक पठनीय हैं
  • हो सकता है कि यह आपको मापदंडों के बिना प्रश्नों के अभ्यस्त बनाता है, तो हो सकता है कि आपने एक बार गलती की हो और इस तरह एक स्ट्रिंग मान का उपयोग करें और फिर आपको संभवतः अपने डेटा को अलविदा कह देना चाहिए। बुरी आदत!


"उत्पाद से चयन करें * कहां Id =" + TextBox1.Text


हालांकि यह आपका सवाल नहीं है, लेकिन शायद भविष्य के पाठकों के लिए उपयोगी है:

सुरक्षा
आपदा!
जब Idफ़ील्ड पूर्णांक होता है, तब भी आपकी क्वेरी SQL इंजेक्शन के अधीन हो सकती है। मान लें कि आपके आवेदन में एक क्वेरी है "SELECT * FROM Table1 WHERE Id=" + TextBox1.Text, एक हमलावर टेक्स्ट बॉक्स में डाल सकता है 1; DELETE Table1और क्वेरी होगी:

"SELECT * FROM Table1 WHERE Id=1; DELETE Table1"

यदि आप यहां पैरामीट्रिक क्वेरी का उपयोग नहीं करना चाहते हैं, तो आपको टाइप किए गए मानों का उपयोग करना चाहिए:

string.Format("SELECT * FROM Table1 WHERE Id={0}", int.Parse(TextBox1.Text))


आपका प्रश्न


मेरा सवाल इसलिए उठा क्योंकि एक सहकर्मी ने पूर्णांक मानों को समेटते हुए प्रश्नों का एक समूह लिखा था, और मैं सोच रहा था कि क्या यह उन सभी के माध्यम से जाने और ठीक करने के लिए मेरे समय की बर्बादी थी।

मुझे लगता है कि उन कोडों को बदलना समय की बर्बादी नहीं है। वास्तव में परिवर्तन की सिफारिश की है!

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


यहां तक ​​कि पहला विकल्प सुरक्षा के लिए पूरी तरह से ठीक नहीं है। का व्यवहार .ToString()एक ऑपरेटिंग सिस्टम कॉन्फ़िगरेशन आइटम द्वारा निर्धारित किया जाता है जो मनमाना पाठ शामिल करने के लिए बदलना आसान है।
जोएल कोएहॉर्न

18

वास्तव में एक में दो प्रश्न हैं। और शीर्षक से सवाल बहुत बाद में टिप्पणियों में ओपी द्वारा व्यक्त की गई चिंताओं के साथ बहुत कम है।

हालाँकि मुझे पता है कि ओपी के लिए यह उनका विशेष मामला है जो मायने रखता है, Google से आने वाले पाठकों के लिए, अधिक सामान्य प्रश्न का उत्तर देना महत्वपूर्ण है, क्योंकि इसे संक्षिप्त किया जा सकता है "यदि मैं सुनिश्चित करूं कि तैयार किए गए बयानों के रूप में सुरक्षित है कि मैं जो हर शाब्दिक हूं वह सुरक्षित है? ”। इसलिए, मैं इस उत्तरार्द्ध पर ध्यान केंद्रित करना चाहूंगा। और जवाब है

निश्चित रूप से नहीं।

स्पष्टीकरण यह नहीं है कि ज्यादातर पाठक चाहेंगे, लेकिन मैं पूरी कोशिश करूंगा।

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

एसक्यूएल इंजेक्शन के सवाल को कुछ विशेष वाक्यविन्यास मुद्दे के मामले में सरल नहीं किया जा सकता है। यह सोचने के लिए इस्तेमाल किए गए औसत डेवलपर की तुलना में व्यापक है। यह एक पद्धतिगत प्रश्न भी है। यह न केवल "हमें किस विशेष प्रारूपण को लागू करना है", बल्कि " यह कैसे करना है" भी है।

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

जब आप सुरक्षा के सवाल को पूरी तरह से नहीं, बल्कि विभिन्न वाक्यविन्यास मुद्दों के एक सेट के रूप में संबोधित करने का प्रयास कर रहे हैं, तो आप समस्याओं का सामना कर रहे हैं।

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

उस गड़बड़ के विपरीत, तैयार कथन वास्तव में पवित्र कंघी बनानेवाले की रेती हैं:

  • इसे एक सरल नियम के रूप में व्यक्त किया जा सकता है जिसका पालन करना आसान है।
  • यह अनिवार्य रूप से अनिर्वचनीय उपाय है, इसका मतलब है कि डेवलपर हस्तक्षेप नहीं कर सकता है, और, स्वेच्छा से या अनिच्छा से, प्रक्रिया को खराब कर सकता है।
  • इंजेक्शन से सुरक्षा वास्तव में तैयार किए गए कथनों का केवल एक पक्ष प्रभाव है, जिसका वास्तविक उद्देश्य वाक्यात्मक रूप से सही कथन का उत्पादन करना है। और एक वाक्यात्मक रूप से सही कथन 100% इंजेक्शन प्रमाण है। फिर भी हमें किसी भी इंजेक्शन की संभावना के बावजूद अपने वाक्यविन्यास को सही होना चाहिए।
  • यदि सभी तरह से उपयोग किया जाता है, तो यह डेवलपर के अनुभव की परवाह किए बिना आवेदन की सुरक्षा करता है। कहते हैं, एक चीज है जिसे दूसरा ऑर्डर इंजेक्शन कहा जाता है । और एक बहुत मजबूत भ्रम जो "रक्षा करने के लिए, सभी उपयोगकर्ता आपूर्ति इनपुट से बच " पढ़ता है । एक साथ संयुक्त, वे इंजेक्शन का नेतृत्व करते हैं, अगर कोई डेवलपर यह तय करने के लिए स्वतंत्रता लेता है कि क्या संरक्षित किया जाना चाहिए और क्या नहीं।

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

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


10
प्रश्न का उत्तर नहीं
edc65

अधिकांश डेटाबेस SQL ​​स्ट्रिंग समानता द्वारा पहले से ही उपयोग किए गए, पैरामीटर किए गए प्रश्नों का पता लगाते हैं, इसलिए पुरानी तैयारी और उपयोग-संभाल विधि मेरे लिए पुरानी लगती है। इन हैंडल का उपयोग केवल एक निश्चित दायरे में किया जा सकता है और हैंडल का ट्रैक रखने के लिए कोडिंग की आवश्यकता होती है। मेरी राय में, पैरामीटर को सीधे उपयोग किया जाना चाहिए, ताकि क्वेरी योजनाओं को बिना किसी ट्रैकिंग और यहां तक ​​कि विभिन्न अनुप्रयोगों के बिना पुन: उपयोग किया जा सके।
एरिक हार्ट

15

आइए केवल सुरक्षा या प्रकार-सुरक्षित विचारों के बारे में न सोचें।

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

जब तक

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

अभी

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

हाँ आप SQL बफर बढ़ा सकते हैं लेकिन यह हमेशा कैशिंग इंडेक्स या डेटा जैसे मेमोरी के लिए अन्य अधिक महत्वपूर्ण उपयोगों की कीमत पर होता है। नैतिक, आप अपने डेटाबेस को अनुकूलित कर सकते हैं और सामान के लिए अधिक सर्वर मेमोरी का उपयोग करने के लिए पैरामीट्रिक प्रश्नों का उपयोग करें।


8

Maciek उत्तर में कुछ जानकारी जोड़ने के लिए:

असेंबली के मुख्य कार्य को प्रतिबिंब द्वारा .NET .NET पार्टी ऐप की संस्कृति जानकारी को बदलना आसान है:

using System;
using System.Globalization;
using System.Reflection;
using System.Threading;

namespace ConsoleApplication2
{
  class Program
  {
    static void Main(string[] args)
    {
      Assembly asm = Assembly.LoadFile(@"C:\BobbysApp.exe");
      MethodInfo mi = asm.GetType("Test").GetMethod("Main");
      mi.Invoke(null, null);
      Console.ReadLine();
    }

    static Program()
    {
      InstallBobbyTablesCulture();
    }

    static void InstallBobbyTablesCulture()
    {
      CultureInfo bobby = (CultureInfo)CultureInfo.InvariantCulture.Clone();
      bobby.DateTimeFormat.ShortDatePattern = @"yyyy-MM-dd'' OR ' '=''";
      bobby.DateTimeFormat.LongTimePattern = "";
      bobby.NumberFormat.NegativeSign = "1 OR 1=1 OR 1=";
      Thread.CurrentThread.CurrentCulture = bobby;
    }
  }
}

यह केवल तभी काम करता है यदि BobbysApp का मुख्य कार्य सार्वजनिक है। यदि मेन सार्वजनिक नहीं है, तो आपके द्वारा कॉल किए जाने वाले अन्य सार्वजनिक कार्य भी हो सकते हैं।


1
आपको इसे कोड द्वारा भी नहीं करना है। आप Windows क्षेत्रीय सेटिंग्स में सीधे इंजेक्शन जोड़ सकते हैं। मेरा जवाब देखिए।
कास्पर्स ओज़ोल्स

2
कौन सर्वर सेटिंग्स बदल सकता है या कौन सर्वर में ऐसे कोड को रगड़ सकता है? यदि कोई व्यक्ति आपके सर्वर में कर सकता है, तो उसे डेटा को नष्ट करने के लिए SQL इंजेक्शन की आवश्यकता नहीं है।
रेजा अगाही

7

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


1
ऐसा नहीं है कि मैं मापदंडों का उपयोग नहीं करना चाहता, मैं मापदंडों का उपयोग कर रहा हूं। एक सहकर्मी ने इस तरह का कोड लिखा था जिसे मैंने आज संशोधित करने के लिए संशोधित किया, जिसने मुझे प्रश्न के बारे में सोचा।
जॉनीरोज 2

ठीक। महान। मापदंडों का उपयोग करने के लिए यह एक सर्वोत्तम प्रथा है। इस तरह आपको sql इंजेक्शन जैसी चीजों के बारे में चिंता करने की ज़रूरत नहीं है। यदि आप एक गतिशील प्रश्नों का निर्माण कर रहे हैं, तो आप उन मापदंडों का भी उपयोग कर सकते हैं, जो आपके प्रश्नों के कितने जटिल हैं। बस उन्हें बनाते समय @ 1 ... @ n शैली का उपयोग करें। और उन्हें वांछित मूल्य के साथ पैरामीटर संग्रह में जोड़ें।
मैक्स

@johnyRose मापदंडों का उपयोग करने के लिए एक और बिंदु है: कार्यक्रम विकसित हो रहा है और बदलता है। आप केवल स्ट्रिंग के लिए संघनन का उपयोग कर सकते हैं, लेकिन यह गारंटी नहीं देता है कि कोई ऐसे रिफ्लेक्टर को लागू करता है जो कुछ पैरामीटर प्रकार को बदलता है और जो परिवर्तन SQL इंजेक्शन भेद्यता को प्रस्तुत कर सकते हैं।
lerthe61

3

यह ठीक है लेकिन कभी सुरक्षित नहीं है .. और सुरक्षा हमेशा इनपुट पर निर्भर करती है, उदाहरण के लिए यदि इनपुट ऑब्जेक्ट टेक्स्टबॉक्स है, तो हमलावर कुछ मुश्किल कर सकते हैं क्योंकि टेक्स्टबॉक्स स्ट्रिंग को स्वीकार कर सकता है, इसलिए आपको किसी प्रकार का सत्यापन / रूपांतरण करना होगा उपयोगकर्ताओं को गलत इनपुट को रोकने में सक्षम होना। लेकिन बात यह है, यह सुरक्षित नहीं है। जैसा कि बस।


हालांकि यह एक स्ट्रिंग है। मैं अन्य डेटा प्रकारों के बारे में बात कर रहा हूं, जैसे पूर्णांक, बूलियन या डेटाटाइम।
जॉनीरोज

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

मुझे वास्तव में कोई संदेह नहीं था कि यह मापदंडों का उपयोग करने के लिए सुरक्षित था। मेरे प्रश्न को दृढ़ता से टाइप किए गए कार्यान्वयन के लिए संदर्भित किया गया है।
जॉनीरोज 2

हाँ .. मैं सहमत हूँ। और यह भी महान सवाल है कि भविष्य के पाठकों की मदद कर सकते हैं :)
japzdivino

-2

नहीं, आप उस तरह से एक SQL इंजेक्शन हमला नहीं कर सकते। मैंने तुर्की में एक पुराना लेख लिखा है जिसमें दिखाया गया है कि यहाँ कैसे । PHP और MySQL में अनुच्छेद उदाहरण लेकिन अवधारणा C # और SQL सर्वर में समान काम करती है।

मूल रूप से आप निम्नलिखित तरीके से हमला करते हैं। विचार करें कि आपके पास एक पृष्ठ है जो पूर्णांक आईडी मान के अनुसार जानकारी दिखाता है। आप नीचे दिए गए मान की तरह इस परिक्रमण नहीं करते हैं।

http://localhost/sqlEnjeksiyon//instructors.aspx?id=24

ठीक है, मुझे लगता है कि आप MySQL का उपयोग कर रहे हैं और मैं निम्नलिखित तरीके से हमला करता हूं।

http://localhost/sqlEnjeksiyon//instructors.aspx?id=ASCII((SELECT%20DATABASE()))

ध्यान दें कि यहां इंजेक्शन का मूल्य स्ट्रिंग नहीं है। हम ASCII फ़ंक्शन का उपयोग करके int के लिए char value बदल रहे हैं। आप "CAST (YourVarcharCol AS INT)" का उपयोग करके SQL सर्वर में एक ही चीज़ को पूरा कर सकते हैं।

उसके बाद मैं आपके डेटाबेस नाम के बारे में जानने के लिए लंबाई और सबस्ट्रिंग फ़ंक्शन का उपयोग करता हूं।

http://localhost/sqlEnjeksiyon//instructors.aspx?id=LEN((SELECT%20DATABASE()))

http://localhost/sqlEnjeksiyon//instructors.aspx?id=ASCII(SUBSTR(SELECT%20DATABASE(),1,1))

फिर डेटाबेस नाम का उपयोग करते हुए, आप डेटाबेस में टेबल नाम प्राप्त करना शुरू करते हैं।

http://localhost/sqlEnjeksiyon//instructors.aspx?id=ASCII(SUBSTR((SELECT table_name FROM INFORMATION_SCHEMA.TABLES LIMIT 1),1,1))

बेशक, आपको इस प्रक्रिया को स्वचालित करना होगा, क्योंकि आपको प्रति क्वेरी केवल एक चरित्र मिलता है। लेकिन आप इसे आसानी से स्वचालित कर सकते हैं। मेरा लेख वातीर में एक उदाहरण दिखाता है । केवल एक पृष्ठ का उपयोग करना और आईडी मान का मानकीकरण नहीं करना। मैं आपके डेटाबेस में हर तालिका का नाम जान सकता हूं। उसके बाद मैं महत्वपूर्ण तालिकाओं की तलाश कर सकता हूं। इसमें समय लगेगा लेकिन यह करने योग्य है।


2
मेरा प्रश्न एक जोरदार टाइप की गई भाषा को संदर्भित करता है। यद्यपि आपका स्पष्टीकरण लचीली टाइपिंग वाली भाषाओं के लिए बहुत अच्छा है, फिर भी इंजेक्शन मूल्य एक स्ट्रिंग है।
johnnyRose

कोई इंजेक्शन मूल्य पूर्णांक नहीं है। आप ASCII MySQL फ़ंक्शन का उपयोग करके चार्ट प्राप्त करते हैं और इसे पूर्णांक में बदलते हैं। आप कास्ट (YourCharValue AS INT) का उपयोग करते हुए SQL सर्वर में एक ही काम करते हैं
Atilla Ozgur

मेरा मतलब कुछ इस तरह से था:public void QuerySomething(int id) { // this will only accept an integer }
johnnyRose

-3

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

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

मान लें कि हमारे पास एक खंड है जहां खंड और:

  1. उपयोगकर्ता-चर एक स्ट्रिंग है। तब ठीक है, इसे इंजेक्ट करना बहुत आसान नहीं है (UNION का उपयोग करके) लेकिन हमलों जैसे 'OR 1 = 1' का उपयोग करके बायपास करना बहुत आसान है ...

  2. यदि उपयोगकर्ता-चर एक पूर्णांक है। फिर हम सिस्टम क्रैश के लिए या फिर एक छिपे हुए बफर अतिप्रवाह (अंतिम स्ट्रिंग पर ...) के लिए असामान्य बड़ी संख्या परीक्षण पास करके सिस्टम की ताकत का 'परीक्षण' कर सकते हैं;);

हो सकता है कि प्रश्नों के पैरामीटर या (और भी बेहतर - imo) स्टोर की गई प्रक्रियाओं के लिए 100% खतरे सुरक्षित नहीं हैं, लेकिन उन्हें कम से कम आवश्यक माप (या यदि आप चाहें तो प्राथमिक) हैं।


मुझे लगता है कि आपको सवाल गलत लगा होगा। मैं के बारे में बात कर रहा हूँ गैर -string प्रकार के।
जॉनीरोज

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