दिलचस्प पोस्ट
सीजीएमके के लिए आरजीबी और एल्गोरिथ्म वापस Google क्लाउड डेटाफ्लो के माध्यम से Parititoned BigQuery तालिका में निर्माण / लेखन जावा में एकाधिक विरासत ऑब्जेक्ट के रूप में वेब एपीआई पद्धति के लिए json POST डेटा कैसे पास करें? कौन सा HTML पार्सर सबसे अच्छा है? ImageMagick का उपयोग कर एक छवि "डिफ" "पहला अवसर अपवाद" क्या है? कमांडलाइन तर्कों के साथ सी # से PowerShell स्क्रिप्ट निष्पादित करें एचटीएमएल 5: क्या यह है, <br/>, या <br />? मैं Cloudant / CouchDB के साथ अपने एसक्यूएल ज्ञान का उपयोग कैसे कर सकता हूं? यह कैसे पता लगाएगा कि कोई चरित्र दाईं ओर वाली भाषा से है या नहीं? HTTP शीर्षलेख IIS7.5 भेजे जाने के बाद सर्वर स्थिति सेट नहीं कर सकता एंड्रॉइड: कुछ गतिविधियों पर एक्शनबार को छिपाने के लिए PHP में पूर्ण यूआरएल प्राप्त करें एक बिंदु से एनीमेशन बढ़ने के साथ संवाद फ्रेग्मेंट दिखाएं

मापदंडों के बिना एसक्यूएल इंजेक्शन से बचना

हमारे कोड में parametrized sql क्वेरी का उपयोग करने के बारे में हम यहां एक और चर्चा कर रहे हैं। चर्चा में हमारे पास दो पक्ष हैं: मेरे और कुछ अन्य लोग कहते हैं कि हमें एसक्वल इंजेक्शन और अन्य लोगों के खिलाफ सुरक्षा के लिए मापदंडों का हमेशा उपयोग करना चाहिए, जो यह नहीं सोचते कि यह आवश्यक है। इसके बजाय वे एसक्यूएल इंजेक्शन से बचने के लिए सभी स्ट्रिंग्स में दो एपोप्रॉफ़्स के साथ एकल एपप्रोफ़ोप्स को बदलना चाहते हैं। हमारे डेटाबेस SQL ​​सर्वर 2005 या 2008 चल रहे हैं और हमारा कोड बेस .NET Framework 2.0 पर चल रहा है।

मैं आपको सी # में एक साधारण उदाहरण देता हूँ:

मैं चाहता हूं कि हम इसका उपयोग करें:

string sql = "SELECT * FROM Users WHERE Name=@name"; SqlCommand getUser = new SqlCommand(sql, connection); getUser.Parameters.AddWithValue("@name", userName); //... blabla - do something here, this is safe 

जबकि अन्य लोग ऐसा करना चाहते हैं:

 string sql = "SELECT * FROM Users WHERE Name=" + SafeDBString(name); SqlCommand getUser = new SqlCommand(sql, connection); //... blabla - are we safe now? 

जहां सुरक्षित डी बी स्ट्रिंग फ़ंक्शन परिभाषित किया गया है:

 string SafeDBString(string inputValue) { return "'" + inputValue.Replace("'", "''") + "'"; } 

अब, जब तक हम अपने प्रश्नों में सभी स्ट्रिंग मानों पर सुरक्षित डीबस्ट्रिंग का प्रयोग करते हैं, तब तक हमें सुरक्षित रहना चाहिए। सही?

SafeDBString फ़ंक्शन का उपयोग करने के दो कारण हैं। सबसे पहले, यह पत्थर की उम्र के बाद से किया गया है, और दूसरा, एसक्यूएल स्टेटमेंट्स को डीबग करना आसान है क्योंकि जब आप डाटाबेस पर चलने वाली सचेतक क्वेरी देखते हैं

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

क्या कोई ऐसा है जो इसे तोड़ सकता है? आपको इसे कैसे करना होगा?

संपादित करें: अभी तक उत्तरों को संक्षेप करने के लिए:

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

इसलिए जब कोई भी SafeDBString फ़ंक्शन की सरल सुरक्षा को तोड़ने में सक्षम नहीं था, तो मुझे बहुत सारे अच्छे तर्क मिले। धन्यवाद!

Solutions Collecting From Web of "मापदंडों के बिना एसक्यूएल इंजेक्शन से बचना"

मुझे लगता है कि सही उत्तर है:

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

मापदंडों का उपयोग करें

और फिर कोई और चला जाता है "का उपयोग करता है '। पैरामीटर हैं, आईएमओ, एकमात्र सुरक्षित रास्ता तय करना है

यह दिनांक / संख्याओं के साथ बहुत सारे i18n मुद्दों से बचा जाता है; दिनांक 01/02/03 क्या है? कितना 123456 है? क्या आपके सर्वर (ऐप-सर्वर और डीबी-सर्वर) प्रत्येक-दूसरे से सहमत हैं?

यदि जोखिम कारक उन्हें समझने के लिए नहीं है, तो प्रदर्शन के बारे में कैसे? यदि आप मापदंडों का उपयोग करते हैं, तो प्रदर्शन की मदद से RDBMS क्वेरी प्लान का पुन: उपयोग कर सकता है। यह केवल स्ट्रिंग के साथ ऐसा नहीं कर सकता

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

यह देखते हुए कि parametrized प्रश्न एक अविवादित प्रोग्रामिंग सर्वोत्तम अभ्यास हैं, साक्ष्य का बोझ उन पर बताने के लिए होना चाहिए कि वे एक ऐसी विधि का उपयोग क्यों नहीं कर रहे हैं जो दोनों सुरक्षित और बेहतर प्रदर्शन कर रहे हैं।

अगर समस्या सभी विरासत कोड को दोबारा लिख ​​रही है, तो आसान समझौता सभी नए कोड में पैरामीटिज्ड क्वेरी का उपयोग करने के लिए होगा, और उस कोड पर कार्य करते समय उन का उपयोग करने के लिए पुराने कोड को रिफैक्टर करेगा।

मेरा अनुमान है कि वास्तविक मुद्दा गर्व और ज़ोरदार है, और आप उस बारे में बहुत कुछ नहीं कर सकते

सबसे पहले, "बदलें" संस्करण के लिए आपका नमूना गलत है आपको टेक्स्ट के चारों ओर एपप्रोफ़ोश डालनी होगी:

 string sql = "SELECT * FROM Users WHERE Name='" + SafeDBString(name) & "'"; SqlCommand getUser = new SqlCommand(sql, connection); 

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

एक अन्य चीज प्रदर्शन है: पैरामीटर वाली क्वेरी प्लान को अक्सर कंसैटेनेटेड प्लान से बेहतर कैश की जाती है, इस प्रकार संभवत: क्वेरी को चलाने के दौरान सर्वर को एक कदम बचाता है

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

x \ 'या 1 = 1; –


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

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

तो मैं कहूंगा:

1) आप उस चीज को पुनः कार्यान्वित करने का प्रयास क्यों कर रहे हैं जो उसमें बनाया गया है? यह वहाँ है, आसानी से उपलब्ध है, उपयोग करने में आसान और पहले से ही वैश्विक स्तर पर डीबग किया गया है अगर भविष्य में कीड़े मिल जाती हैं, तो उन्हें तय कर लिया जाएगा और हर किसी के बिना बहुत कुछ जल्दी ही आपको उपलब्ध कराएगा।

2) यह गारंटी देने के लिए क्या प्रक्रियाएं मौजूद हैं कि आप कभी भी SafeDBString के लिए कॉल नहीं छोड़ते हैं? इसे सिर्फ 1 स्थान में लापता होने से पूरे मामले में समस्याएं खुल सकती हैं आप इन चीजों को कबूल करने जा रहे हैं, और यह विचार करें कि यह प्रयास कितना व्यर्थ है जब स्वीकार्य सही उत्तर इतनी आसानी से पहुंच जाए।

3) आप कितने निश्चित हैं कि आपने हर हमले के वेक्टर को कवर किया है, जो कि माइक्रोसॉफ्ट (डीबी और एक्सेस लाइब्रेरी के लेखक) आपके सुरक्षित डीबस्ट्रिंग कार्यान्वयन में जानता है …

4) एसक्यूएल की संरचना को पढ़ने में कितना आसान है? उदाहरण + concatenation का उपयोग करता है, पैरामीटर स्ट्रिंग की तरह बहुत हैं। फॉर्मेट, जो अधिक पठनीय है।

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

हमारा लॉग कॉमांड फ़ंक्शन बस है:

  string LogCommand(SqlCommand cmd) { StringBuilder sb = new StringBuilder(); sb.AppendLine(cmd.CommandText); foreach (SqlParameter param in cmd.Parameters) { sb.Append(param.ToString()); sb.Append(" = \""); sb.Append(param.Value.ToString()); sb.AppendLine("\""); } return sb.ToString(); } 

सही या गलत, यह हमें सुरक्षा संबंधी समस्याओं के बिना हमें जो सूचना देता है वह देता है

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

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

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

अगर आप डीबी कॉल्स बनाने के लिए SQLCommand और SQLParameter कक्षाओं का उपयोग करते हैं, तो आप अभी भी एसक्यूएल क्वेरी को देख सकते हैं जिसे निष्पादित किया जा रहा है। SQLCommand के CommandText संपत्ति को देखें

जब मैं पैरामीटर वाली क्वेरीज़ का इस्तेमाल करना इतना आसान होता है तो मैं हमेशा एसक्यूएल इंजेक्शन को रोकने के लिए रोल्स-अपने-खुद के दृष्टिकोण के लिखित एक संदेहास्पद हूँ दूसरा, सिर्फ इसलिए कि "हमेशा ऐसा किया जाता है" इसका यह अर्थ नहीं है कि यह करने का सही तरीका है।

यह केवल तभी सुरक्षित है यदि आपको गारंटी दी जाती है कि आप स्ट्रिंग में पास होने जा रहे हैं।

क्या होगा अगर आप किसी बिंदु पर स्ट्रिंग में नहीं जा रहे हैं? क्या होगा अगर आप केवल एक संख्या पास करते हैं?

 http://www.mywebsite.com/profile/?id=7;DROP DATABASE DB 

अंततः बन जाएगा:

 SELECT * FROM DB WHERE Id = 7;DROP DATABASE DB 

मैं सब कुछ के लिए संग्रहीत कार्यविधियों या कार्यों का उपयोग करता हूं, इसलिए प्रश्न उत्पन्न नहीं होगा

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

सुरक्षा मुद्दों पर बेहद सहमति दें
मापदंडों का उपयोग करने का एक और कारण दक्षता के लिए है

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

यदि आप मापदंडों को बाध्य नहीं करते हैं, तो एसक्यूएल स्ट्रिंग हर अनुरोध पर बदलती है (जिसमें अलग-अलग मापदंड हैं) और यह आपके कैश में क्या मेल नहीं खाएगा।

बहुत ही कम समय से मुझे एसक्यूएल इंजेक्शन की समस्याओं की जांच करनी पड़ती है, मैं देख सकता हूं कि मूल्य 'सुरक्षित' बनाने का मतलब यह भी है कि आप ऐसे परिस्थितियों के लिए दरवाजा बंद कर रहे हैं जहां आप वास्तव में अपने डेटा में अपॉरोपॉप्स चाहते हैं – किसी के नाम के बारे में , जैसे ओ रेली

वह मापदंडों और संग्रहित प्रक्रियाओं को छोड़ देता है

और हां, आपको हमेशा पता चलने का सबसे अच्छा तरीका कोड को कार्यान्वित करने की कोशिश करनी चाहिए – न कि यह हमेशा कैसे किया गया है।

यहां कुछ ऐसे लेख दिए गए हैं जो आपके सहकर्मियों को समझाने में सहायक हो सकते हैं।

http://www.sommarskog.se/dynamic_sql.html

http://unixwiz.net/techtips/sql-injection.html

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

यह टूटा जा सकता है, हालांकि इसका अर्थ सटीक संस्करण / पैच आदि पर निर्भर करता है।

एक जो पहले से ही लाया गया है वह अतिप्रवाह / कटौती बग है जिसका इस्तेमाल किया जा सकता है।

एक और भविष्य का मतलब अन्य डेटाबेस के समान बगों को खोजना होगा – उदाहरण के लिए, MySQL / PHP स्टेक से बचने की समस्या का सामना करना पड़ता है क्योंकि कुछ यूटीएफ 8 अनुक्रमों को फ़ंक्शन को फेरबदल करने के लिए इस्तेमाल किया जा सकता है – प्रतिस्थापन फ़ंक्शन इंजेक्शन वर्णों को शुरू करने में धोखा दिया जाएगा

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

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

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

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

 var bldr = new SqlBuilder( myCommand ); bldr.Append("SELECT * FROM CUSTOMERS WHERE ID = ").Value(myId, SqlDbType.Int); //or bldr.Append("SELECT * FROM CUSTOMERS WHERE NAME LIKE ").FuzzyValue(myName, SqlDbType.NVarChar); myCommand.CommandText = bldr.ToString(); 

कोड पठनीयता, मुझे आशा है कि आप सहमत हैं, बहुत सुधार हुआ है, और आउटपुट एक उचित पैरामीटर की गई क्वेरी है

वर्ग इस तरह दिखता है …

 using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; namespace myNamespace { /// <summary> /// Pour le confort et le bonheur, cette classe remplace StringBuilder pour la construction /// des requêtes SQL, avec l'avantage qu'elle gère la création des paramètres via la méthode /// Value(). /// </summary> public class SqlBuilder { private StringBuilder _rq; private SqlCommand _cmd; private int _seq; public SqlBuilder(SqlCommand cmd) { _rq = new StringBuilder(); _cmd = cmd; _seq = 0; } //Les autres surcharges de StringBuilder peuvent être implémenté ici de la même façon, au besoin. public SqlBuilder Append(String str) { _rq.Append(str); return this; } /// <summary> /// Ajoute une valeur runtime à la requête, via un paramètre. /// </summary> /// <param name="value">La valeur à renseigner dans la requête</param> /// <param name="type">Le DBType à utiliser pour la création du paramètre. Se référer au type de la colonne cible.</param> public SqlBuilder Value(Object value, SqlDbType type) { //get param name string paramName = "@SqlBuilderParam" + _seq++; //append condition to query _rq.Append(paramName); _cmd.Parameters.Add(paramName, type).Value = value; return this; } public SqlBuilder FuzzyValue(Object value, SqlDbType type) { //get param name string paramName = "@SqlBuilderParam" + _seq++; //append condition to query _rq.Append("'%' + " + paramName + " + '%'"); _cmd.Parameters.Add(paramName, type).Value = value; return this; } public override string ToString() { return _rq.ToString(); } } } 

मुझे नहीं पता था कि किसी भी अन्य answsers 'यह क्यों कर खुद बुरा है' के इस ओर से संबोधित करते हैं, लेकिन एक एसक्यूएल truncation हमले पर विचार

वहां QUOTENAME टी-एसक्यूएल फ़ंक्शन भी है जो सहायक हो सकता है यदि आप उन्हें पैरामीटर का उपयोग करने के लिए मना नहीं कर सकते हैं यह बच गए qoute चिंताओं की एक बहुत (सभी?) कैच?

पैरामीटर वाले क्वेरीज़ का उपयोग करने के कुछ कारण यहां दिए गए हैं:

  1. सुरक्षा – डाटाबेस एक्सेस परत जानता है कि डेटा में अनुमति नहीं दी जाने वाली वस्तुओं को कैसे निकालना या बचाना है।
  2. चिंताओं का पृथक्करण – मेरा कोड डेटा को उस प्रारूप में बदलने के लिए ज़िम्मेदार नहीं है, जो डेटाबेस को पसंद करता है।
  3. कोई अतिरेक नहीं – मुझे प्रत्येक प्रोजेक्ट में असेंबली या कक्षा शामिल करने की आवश्यकता नहीं है जो यह डेटाबेस फ़ॉर्मेटिंग / एस्केपिंग करता है; यह कक्षा पुस्तकालय में बनाया गया है

कुछ कमजोरियों (मुझे यह याद नहीं है कि यह डेटाबेस कौन सा था) जो बफर ओफ़्फ़्लो से संबंधित SQL कथन का है

मैं क्या कहना चाहता हूं, एसक्यूएल-इंजेक्शन अधिक है तो बस "उद्धरण से बचें", और आपको नहीं पता कि आगे क्या आता है।

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

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

हमेशा संभव मानकीकृत क्वेरीज़ का उपयोग करें कभी-कभी किसी भी अजीब अक्षर के उपयोग के बिना भी एक सरल इनपुट एक एसक्यूएल-इंजेक्शन बना सकता है अगर यह डेटाबेस में एक फ़ील्ड के लिए इनपुट के रूप में नहीं पहचाना जाता है।

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

2 साल बाद , मैंने पुनर्कथन किया … जो कोई भी पैरामीटर को ढूंढता है वह दर्द है, मेरे वी.एस. एक्स्टेंशन, क्वेरीफस्ट की कोशिश करने के लिए स्वागत है आप अपने अनुरोध को एक वास्तविक .sql फ़ाइल (मान्यकरण, Intellisense) में संपादित कर सकते हैं। एक पैरामीटर जोड़ने के लिए, आप इसे सीधे 'एस' में टाइप करते हैं, जो कि '@' से शुरू होता है जब आप फ़ाइल को सहेजते हैं, QueryFirst आवरण क्लास उत्पन्न करने के लिए आपको क्वेरी चलाने और परिणाम तक पहुंचने के लिए। यह आपके पैरामीटर के डीबी प्रकार को देखेगा और उसे एक .net प्रकार में मैप करेगा, जो आपको उत्पन्न Execute () विधियों के लिए एक इनपुट के रूप में मिलेगा। सरल नहीं हो सका इसे सही तरीके से करना यह तेज और तेज है कि यह किसी भी अन्य तरीके से कर रही है, और एक एसक्यूएल इंजेक्शन भेद्यता पैदा करना असंभव हो जाता है, या कम से कम विकृत रूप से मुश्किल हो सकता है आपके हत्यारे के अन्य लाभ हैं, जैसे कि अपने डीबी में कॉलम हटाने में सक्षम होने के साथ-साथ तुरंत अपने आवेदन में त्रुटियों के संकलन देखें।

कानूनी अस्वीकरण: मैंने QueryFirst लिखा था