क्या मैं एकल-उद्धरणों के साथ एकल-उद्धरण और आसपास के उपयोगकर्ता इनपुट से बचकर SQL इंजेक्शन से रक्षा कर सकता हूं?


139

मुझे एहसास हुआ कि पैरामीटर क्वेरी एसक्यूएल उपयोगकर्ता इनपुट का निर्माण करते समय उपयोगकर्ता इनपुट को साफ करने का सबसे इष्टतम तरीका है, लेकिन मैं सोच रहा हूं कि उपयोगकर्ता इनपुट लेने और किसी भी एकल उद्धरण से बचने और एकल उद्धरण के साथ पूरे स्ट्रिंग के आसपास क्या गलत है। यहाँ कोड है:

sSanitizedInput = "'" & Replace(sInput, "'", "''") & "'"

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

हम Microsoft SQL Server 2000 का उपयोग कर रहे हैं, जिसके लिए मेरा मानना ​​है कि एकल-उद्धरण स्ट्रिंग स्ट्रिंग सीमांकक और स्ट्रिंग सीमांकक से बचने का एकमात्र तरीका है, इसलिए उपयोगकर्ता प्रकारों में कुछ भी निष्पादित करने का कोई तरीका नहीं है।

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

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


अपडेट करें:

मुझे अभी भी इस कोड के खिलाफ SQL इंजेक्शन हमले को प्रभावी ढंग से लॉन्च करने का कोई तरीका नहीं पता है। कुछ लोगों ने सुझाव दिया कि एक बैकस्लैश एक एकल-उद्धरण से बच जाएगा और दूसरे को स्ट्रिंग को समाप्त करने के लिए छोड़ देगा ताकि शेष स्ट्रिंग को SQL कमांड के हिस्से के रूप में निष्पादित किया जा सके, और मुझे पता है कि यह विधि SQL को इंजेक्ट करने के लिए काम करेगी एक MySQL डेटाबेस, लेकिन SQL Server 2000 में एकमात्र तरीका (जो मुझे मिल गया है) एक एकल-उद्धरण से बचने के लिए किसी अन्य एकल-उद्धरण के साथ है; बैकस्लैश ऐसा नहीं करेंगे।

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

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


17
@BryanH यह समझने की कोशिश नहीं कर रहा है कि एक विशिष्ट मामले में आमतौर पर स्वीकृत ज्ञान कैसे लागू होता है और इस तरह के विशिष्ट मामले के बारे में एक उदाहरण के लिए पूछना पितृसत्ता नहीं है, यह विनम्रता है। जब कोई व्यक्ति इस बात का उदाहरण देता है कि आम तौर पर स्वीकृत ज्ञान क्यों सही है, तो वह नाराज हो जाता है। विशिष्ट उदाहरणों द्वारा तर्क करना अक्सर जांच और सीखने का एक शानदार तरीका है। जिस तरह से ओपी इस संदेह के बारे में गया, वह विषय की मेरी समझ के लिए बहुत उपयोगी था, खासकर जब उसने जो उत्तर पाया उसे समझाया।
शांतिबेलर्स

@patrik बस इस पर आया क्योंकि मैं कोड के एक ही टुकड़े पर काम कर रहा हूं, लेकिन स्ट्रिंग और घोंसले से बचने की कोशिश कर रहा हूं। क्या आपने कभी इसका पता लगाया?
3therk1ll

1
@ 3therk1 सभी को आज़माने के लिए सबसे अच्छा नहीं है, आप बेहतर तरीके से पैरामीटर SQL का उपयोग कर रहे हैं: blog.codinghorror.com/…
पैट्रिक

@ पैट्रिक, मैं इसे हमलावरों के दृष्टिकोण से आ रहा हूं!
3therk1ll

जवाबों:


87

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

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

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

इसे करने का उचित तरीका:

  • श्वेतसूची सत्यापन: प्रकार, लंबाई, प्रारूप या स्वीकृत मान
  • यदि आप ब्लैकलिस्ट करना चाहते हैं, तो ठीक आगे बढ़ें। उद्धरण बचना अच्छा है, लेकिन अन्य उपशमन के संदर्भ में।
  • तैयार करने और मान्य करने के लिए कमांड और पैरामीटर ऑब्जेक्ट का उपयोग करें
  • केवल पैरामीटर वाले प्रश्नों को कॉल करें।
  • बेहतर अभी तक, विशेष रूप से संग्रहीत प्रक्रियाओं का उपयोग करें।
  • डायनेमिक SQL का उपयोग करने से बचें, और क्वेरीज़ बनाने के लिए स्ट्रिंग कॉन्फेंशन का उपयोग न करें।
  • यदि एसपी का उपयोग कर रहे हैं, तो आप केवल आवश्यक एसपी को निष्पादित करने के लिए डेटाबेस में अनुमतियों को सीमित कर सकते हैं, और सीधे तालिकाओं तक नहीं पहुंच सकते हैं।
  • आप यह भी आसानी से सत्यापित कर सकते हैं कि संपूर्ण कोडबेस केवल एसपी के माध्यम से डीबी तक पहुंचता है ...

2
जब सही ढंग से उपयोग किया जाता है, तो डायनामिक एसक्यूएल और स्ट्रिंग कॉन्टेक्नेशन को पैरामीटर किए गए प्रश्नों (अर्थात के sp_executesqlबजाय EXEC) के साथ सुरक्षित रूप से उपयोग किया जा सकता है । यही है, आप गतिशील रूप से अपने एसक्यूएल स्टेटमेंट को तब तक उत्पन्न कर सकते हैं जब तक उपयोगकर्ता से कोई भी संक्षिप्त पाठ नहीं आता है। यह भी प्रदर्शन लाभ है; sp_executesqlकैशिंग का समर्थन करता है।
ब्रायन

2
@ ब्रायन, वेल डह :)। लेकिन वास्तव में, आप प्रोग्रामर को कितनी बार देखते हैं? इसके अलावा, विशिष्ट परिदृश्य जहां डायनेमिक SQL "आवश्यक" है, क्वेरी (माना जाता है) के हिस्से के रूप में उपयोगकर्ता इनपुट की आवश्यकता होती है। यदि आप sp_executesql कर सकते हैं, तो आपको (आमतौर पर) पहले स्थान पर गतिशील sql की आवश्यकता नहीं होगी।
एवीडी

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

1
@ElRonnoco ज़रूर, लेकिन मुझे यह छूट नहीं है, क्योंकि मैंने इसे जंगली बार में देखा है जितना आप सोचते हैं ...
AviD

1
@ एवीडी मैंने एसक्यूएल तस्करी पीडीएफ के लिंक को अपडेट किया जो आपने केवल ऑनलाइन संस्करण में लिखा था जो मुझे ऑनलाइन मिल सकता है ... कृपया हमें बताएं कि क्या आपके पेपर के लिए कोई अन्य स्थान है।
माइकल फ्रेडरिकसन

41

ठीक है, यह प्रतिक्रिया प्रश्न के अद्यतन से संबंधित होगी:

"अगर किसी को इस स्वच्छता पद्धति के खिलाफ एक एसक्यूएल इंजेक्शन हमले को माउंट करने का कोई विशिष्ट तरीका पता है तो मैं इसे देखना पसंद करूंगा।"

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

sSanitizedInput = "" और बदलें (sInput, "'", "'" ") &" "

ध्यान रखें कि ये सभी हर समय मान्य नहीं होंगे, और इसके चारों ओर आपके वास्तविक कोड पर बहुत निर्भर हैं:

  1. सेकेंड-ऑर्डर SQL इंजेक्शन - यदि किसी SQL क्वेरी को डेटाबेस से पुनर्प्राप्त करने के बाद भागने के बाद प्राप्त डेटा के आधार पर फिर से बनाया जाता है , तो डेटा को अप्रकाशित किया जाता है और अप्रत्यक्ष रूप से SQL-इंजेक्ट किया जा सकता है। देख
  2. स्ट्रिंग ट्रंकेशन - (थोड़ा अधिक जटिल) - परिदृश्य आपके पास दो फ़ील्ड हैं, एक उपयोगकर्ता नाम और पासवर्ड कहें, और एसक्यूएल दोनों को समेटता है। और दोनों क्षेत्रों (या सिर्फ पहले) की लंबाई पर एक कठिन सीमा है। उदाहरण के लिए, उपयोगकर्ता नाम 20 वर्णों तक सीमित है। कहो कि आपके पास यह कोड है:
username = left(Replace(sInput, "'", "''"), 20)

फिर आपको जो मिलता है - वह उपयोगकर्ता नाम है, बच गया, और फिर 20 वर्णों तक छंटनी की गई। यहाँ समस्या - मैं अपने उद्धरण को २० वें वर्ण (जैसे १ ९ के बाद) में चिपका दूंगा, और आपकी भागने की बोली छंटनी होगी (२१ वें वर्ण में)। फिर एसक्यूएल

sSQL = "select * from USERS where username = '" + username + "'  and password = '" + password + "'"

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


28

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


2
क्या होगा अगर आपको "Google फ़्यूज़न टेबल" जैसी किसी चीज़ से निपटना है, जहाँ, afaik, कोई भी एब्सट्रैक्शन लाइब्रेरी उपलब्ध नहीं है जो इसकी बोली का समर्थन करती है? आप क्या सुझाव देंगे?
systempuntoout

20

मुझे लगता है कि यह एक लंबे समय के बाद सवाल पूछा गया था, लेकिन ..

स्ट्रिंग द ट्रंचेशन के साथ 'उद्धरण दलील' प्रक्रिया पर हमला शुरू करने का एक तरीका है। MSDN के अनुसार, SQL Server 2000 SP4 (और SQL सर्वर 2005 SP1) में, बहुत लंबा स्ट्रिंग चुपचाप काट दिया जाएगा।

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

यह संभवतः एक 'उपयोगकर्ता व्यवस्थापक' पृष्ठ के परिदृश्य में उपयोगी होगा, जहाँ आप 'अपडेट' कथन का दुरुपयोग कर सकते हैं, यह करने के लिए कि यह सभी चेक नहीं करना चाहिए था।

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

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


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

10

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

अपने आप में यह सुरक्षित AFAIK है। जैसा कि एक अन्य उत्तरदाता ने कहा है, हालांकि, आपको बैकस्पेस से बचने (भले ही ADO या ADO.NET का उपयोग करके SQL सर्वर से क्वेरी पास करते समय न हो, से निपटने की आवश्यकता हो सकती है - सभी डेटाबेस या तकनीकों के लिए वाउच नहीं कर सकता)।

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

हालांकि, ज्यादातर मामलों में, पैरामीटर बाइंडिंग जाने का तरीका है - यह सिर्फ सरल है।


2
यदि आप अपने स्वयं के प्रश्नों का निर्माण कर रहे हैं, तब भी आप पैरामीटर प्रतिस्थापन का उपयोग कर सकते हैं।
निक जॉनसन

1
आपको खरोंच से SQL स्टेटमेंट स्ट्रिंग का निर्माण करना चाहिए, लेकिन फिर भी पैरामीटर प्रतिस्थापन का उपयोग करें।
JeeBee

नहीं, कभी भी अपने SQL स्टेटमेंट को स्क्रैच से न बनाएं।
एवीडी

8

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


4
और जब आप उस वन केस ऑन वन इनपुट को मिस करते हैं, तो आप pwnd हो जाते हैं।
ब्रायन एचएच

4
"कुछ लोग, जब एक समस्या का सामना करते हैं, तो सोचते हैं" मुझे पता है, मैं नियमित अभिव्यक्ति का उपयोग करूंगा। अब उन्हें दो समस्याएं हैं। "
मिकीफ़ेगैन_एफ़र एक्सिट ओफ़्सो

1
@mickeyf मुझे पता है कि यह एक सामान्य भावना है, लेकिन ईमानदारी से नियमित रूप से अभिव्यक्त करने के लिए बहुत बढ़िया हैं जब आप उन्हें समझ लेते हैं।
tom.dietrich 10

@ tom.dietrich यह हमेशा वास्तविक जीवन की स्थिति पर निर्भर करता है। F.ex. regexpr सिंटैक्स मानक नहीं है इसलिए सामान्य रूप से मैं संदर्भों में regexpr का उपयोग करने के खिलाफ सलाह दूंगा जहां विभिन्न प्रणालियों को एक साथ काम करने के लिए एकीकृत किया गया है। ऐसा इसलिए है क्योंकि अलग-अलग regexpr इंजन अलग-अलग तरीके से regexprs का मूल्यांकन करते हैं, और इससे भी महत्वपूर्ण बात यह है कि इस कठिन तथ्य को आमतौर पर उपेक्षित या अनदेखा किया जाता है जो डेवलपर्स को इन असंगतियों की परवाह नहीं कर सकता जब तक कि वे काट न लें। इस तरह की विसंगतियां बहुत हैं; f.ex देखें। नियमित-expressions.info/shorthand.html ( flavorsउस पृष्ठ में खोज करें )।
शांतिबेलर्स जू

6

वैसे भी यह एक बुरा विचार है जैसा कि आप जानते हैं।

कुछ इस तरह से स्ट्रिंग में बोली से बचने के बारे में क्या: \ '

आपकी जगह परिणाम होगा: \ ''

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


3
जवाब देने के लिए धन्यवाद! मुझे पता है कि हमला एक mySQL डेटाबेस के लिए काम करेगा, लेकिन मुझे पूरा यकीन है कि MS SQL सर्वर एक बैकस्लैश को भागने वाले चरित्र के रूप में स्वीकार नहीं करेगा (मैंने इसे आज़माया)। कई Google खोजों ने किसी अन्य भागने वाले चरित्र को प्रकट नहीं किया, जिसने मुझे वास्तव में आश्चर्यचकित किया कि यह काम क्यों नहीं करेगा।
पैट्रिक

6

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

वहाँ किसी भी प्रयोग करने योग्य ब्लैकलिस्ट के आसपास तरीके हैं (और कुछ श्वेतसूची भी)।

एक सभ्य लेखन यहाँ है: http://www.owasp.org/index.php/Top_10_2007-A2

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


6

इसे करने के दो तरीके हैं, कोई अपवाद नहीं, SQL- इंजेक्शन से सुरक्षित होना; तैयार किए गए विवरण या संग्रहीत प्रक्रियाओं को चुभाना।


4

यदि आपके पास पैरामीटरयुक्त प्रश्न उपलब्ध हैं, तो आपको हर समय उनका उपयोग करना चाहिए। यह सब एक जाल के माध्यम से पर्ची के लिए एक क्वेरी के लिए है और आपका DB जोखिम में है।


4

हाँ, यह सही काम करना चाहिए जब तक कोई SET QUOTED_IDENTIFIER OFF नहीं चलाता है और आप पर एक डबल उद्धरण का उपयोग करता है।

संपादित करें: दुर्भावनापूर्ण उपयोगकर्ता को उद्धृत पहचानकर्ताओं को बंद करने की अनुमति नहीं देना उतना आसान नहीं है:

SQL सर्वर मूल क्लाइंट ODBC ड्राइवर और SQL सर्वर के लिए SQL सर्वर मूल क्लाइंट OLE DB प्रदाता स्वचालित रूप से कनेक्ट होने पर QUOTED_IDENTIFIER सेट करते हैं। इसे ODBC डेटा स्रोतों, ODBC कनेक्शन विशेषताओं या OLE DB कनेक्शन गुणों में कॉन्फ़िगर किया जा सकता है। SET QUOTED_IDENTIFIER के लिए डिफ़ॉल्ट DB- लाइब्रेरी अनुप्रयोगों से कनेक्शन के लिए बंद है।

जब एक संग्रहीत कार्यविधि बनाई जाती है, तो SET QUOTED_IDENTIFIER और SET ANSI_NULLS सेटिंग्स कैप्चर की जाती हैं और उस संग्रहीत कार्यविधि के बाद के इनवोकेशन के लिए उपयोग की जाती हैं

SET QUOTED_IDENTIFIER भी ALAT DATABASE की QUOTED_IDENTIFER सेटिंग से मेल खाता है।

सेट QUOTED_IDENTIFIER पार्स समय पर सेट किया गया है । पार्स समय पर सेट करने का मतलब है कि अगर SET स्टेटमेंट बैच या संग्रहित प्रक्रिया में मौजूद है, तो यह प्रभावी होता है, चाहे कोड निष्पादन वास्तव में उस बिंदु तक पहुंच जाए; और किसी भी स्टेटमेंट को निष्पादित करने से पहले SET स्टेटमेंट प्रभावी हो जाता है।

ऐसे कई तरीके हैं जिन्हें QUOTED_IDENTIFIER आपके बिना जरूरी समझे बंद कर सकता है। बेशक - यह धूम्रपान बंदूक का शोषण नहीं है जिसे आप ढूंढ रहे हैं, लेकिन यह एक बहुत बड़ी हमले की सतह है। बेशक, अगर आप भी दोहरे उद्धरणों से बच गए हैं - तो हम वापस आ गए हैं जहाँ हमने शुरुआत की है। ;)


1
यह काम कर सकता है, लेकिन फिर, वे उस कोड को निष्पादित करने के लिए कैसे प्राप्त कर सकते हैं जब सभी उपयोगकर्ता इनपुट एकल उद्धरण से घिरा हुआ है? कोड की एक विशिष्ट लाइन (एस) जो SQL को उपरोक्त कोड में इंजेक्ट करने में सक्षम होगी, बहुत उपयोगी होगी। धन्यवाद!
पैट्रिक

4

आपकी रक्षा विफल हो जाएगी अगर:

  • क्वेरी स्ट्रिंग के बजाय संख्या की अपेक्षा कर रही है
  • एकल उद्धरण चिह्न का प्रतिनिधित्व करने के लिए कोई अन्य तरीका था, जिसमें शामिल हैं:
    • एक भागने का क्रम जैसे कि 039
    • एक यूनिकोड चरित्र

(बाद वाले मामले में, यह कुछ ऐसा होगा जो आपके द्वारा आपकी जगह किए जाने के बाद ही विस्तारित किया गया था)


4

पैट्रिक, क्या आप सभी इनपुट, यहां तक ​​कि संख्यात्मक इनपुट के आसपास एकल उद्धरण जोड़ रहे हैं? यदि आपके पास संख्यात्मक इनपुट है, लेकिन इसके चारों ओर एकल उद्धरण नहीं डाल रहे हैं, तो आपके पास एक जोखिम है।


1

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

इसके अलावा पहिया को क्यों मजबूत करें?


1

एक एकल उद्धरण (जो दिखता है) दो एकल उद्धरणों को बदलने के बजाय, इसे केवल एक एपॉस्ट्रॉफ़, एक उद्धरण, या इसे पूरी तरह से हटाने के लिए क्यों नहीं बदला जाए?

किसी भी तरह से, यह एक कीचड़ का एक सा है ... खासकर जब आप वैध रूप से (जैसे नाम) चीजें हैं जो एकल उद्धरण का उपयोग कर सकते हैं ...

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


डाउन वोट दिया क्योंकि जवाब सवाल का जवाब नहीं देता है। प्रश्न SQL में तार से बचने के बारे में है। जब आप एक मनमाना स्ट्रिंग से बचते हैं (जैसा कि प्रश्नकर्ता अनिश्चित डेटा से निपटने के लिए करने की कोशिश कर रहा है), तो आप समस्याग्रस्त पात्रों को मनमाने ढंग से अन्य लोगों के साथ बदल नहीं सकते हैं; डेटा को दूषित करता है। (इसके अलावा, एक एकल उद्धरण एक अपॉस्ट्रॉफी है (कम से कम ASCII में)।)
andrewf

-1

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

यह बहुत अतिरिक्त काम है।


-2

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


-3

हाँ, आप कर सकते हैं, यदि ...

विषय का अध्ययन करने के बाद, मुझे लगता है कि आपके द्वारा सुझाए गए इनपुट सुरक्षित हैं, लेकिन केवल इन नियमों के तहत:

  1. आप कभी भी स्ट्रिंग सेटरल्स (अर्थात कॉन्फ़िगरेशन विकल्प देने से बचें: "अतिरिक्त SQL कॉलम नाम / भाव यहाँ दर्ज करें):" स्ट्रिंग्स (संख्या, दिनांक, ...) के अलावा अन्य प्रकार: उन्हें अपने मूल डेटा प्रकारों में परिवर्तित करें और अपने डेटा प्रकार से SQL शाब्दिक के लिए एक रूटीन प्रदान करें।

    • SQL कथनों को मान्य करने के लिए समस्याग्रस्त हैं
  2. आप या तो nvarchar/ ncharकॉलम (और उपसर्ग स्ट्रिंग शाब्दिक के साथ N) का उपयोग करते हैं या ASCII वर्णों में varchar/ charकॉलम में जाने वाले मानों को सीमित करते हैं (उदाहरण एसक्यूएल स्टेटमेंट बनाते समय अपवाद फेंकें)

    • इस तरह आप CHAR (700) से CHAR (39) और (शायद अन्य समान यूनिकोड हैक्स) से स्वचालित एपोस्ट्रोफ रूपांतरण से बच जाएंगे।
  3. आप हमेशा वास्तविक कॉलम लंबाई फिट करने के लिए मान लंबाई को मान्य करते हैं (यदि लंबे समय तक अपवाद फेंकें)

    • एसक्यूएल सर्वर में एक ज्ञात दोष था जो ट्रंकेशन पर फेंके गए एसक्यूएल त्रुटि को बायपास करने की अनुमति देता है (मौन ट्रंकेशन की ओर जाता है)
  4. आप SET QUOTED_IDENTIFIERहमेशा सुनिश्चित करते हैंON

    • सावधान रहें, इसे पार्स-टाइम में लागू किया जाता है, अर्थात कोड के दुर्गम वर्गों में भी

इन 4 बिंदुओं का अनुपालन करते हुए, आपको सुरक्षित होना चाहिए। यदि आप उनमें से किसी का उल्लंघन करते हैं, तो SQL इंजेक्शन के लिए एक रास्ता खुल जाता है।


1
यह ऐसा है जैसे आपने इस 8 साल पुराने प्रश्न के अन्य सभी उत्तर नहीं पढ़े हैं , क्योंकि इनमें से कोई भी उत्तर इंगित करता है कि यदि हमलावर बस यूनिकोड वर्ण का उपयोग करता है तो उसका तरीका इंजेक्शन को रोकने में विफल रहता है
होगन

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

ठीक है, जब (यदि नहीं) तो आपके सिस्टम से समझौता हो जाता है कृपया वापस आएँ और इस उत्तर को हटा दें .... या आप एक पैराड्राइज्ड क्वेरी का उपयोग कर सकते हैं।
होगन

@ होगन - मुझे इसे करने में कोई समस्या नहीं है :) लेकिन वर्तमान में मैं दावा करता हूं कि इसके आसपास जाने का कोई ज्ञात तरीका नहीं है यदि आप मेरे द्वारा पोस्ट किए गए 4 नियम रखते हैं। यदि आप वास्तव में सोचते हैं कि इसके आस-पास कोई रास्ता है, तो बस इंगित करें कि कहां है।
21

बुरी सलाह होमब्रिज। किसी भी प्रक्षेप को हराया जा सकता है।
शायनी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.