एसक्यूएल इंजेक्शन निवारक तंत्र पैरामीटरयुक्त प्रश्नों का उपयोग करने की दिशा में क्यों विकसित हुआ?


59

जिस तरह से मैं इसे देखता हूं, SQL इंजेक्शन के हमलों को रोका जा सकता है:

  1. ध्यान से स्क्रीनिंग, फ़िल्टरिंग, एन्कोडिंग इनपुट (एसक्यूएल में प्रविष्टि से पहले)
  2. तैयार किए गए कथनों / परिमाणित प्रश्नों का उपयोग करना

मुझे लगता है कि प्रत्येक के लिए पेशेवरों और विपक्ष हैं, लेकिन क्यों # 2 को हटा दिया गया और इंजेक्शन हमलों को रोकने के लिए डी या वास्तव में तरीका माना जाता है? क्या यह सिर्फ सुरक्षित है और त्रुटि के लिए कम या अन्य कारक थे?

जैसा कि मैं समझता हूं, अगर # 1 का ठीक से उपयोग किया जाता है और सभी कैविटी का ध्यान रखा जाता है, तो यह # 2 के समान प्रभावी हो सकता है।

Sanitizing, फ़िल्टरिंग, और एन्कोडिंग

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

लाइब्रेरी को एन्कोडिंग करने के लिए पैरामीटर क्वेरीज़

ऐसे उत्तर हैं जहां अवधारणाओं parameterized queriesऔर encoding librariesपरस्पर व्यवहार किया जाता है। अगर मैं गलत हूं तो मुझे सुधारो, लेकिन मैं इस धारणा के तहत हूं कि वे अलग हैं।

मेरी समझ यह है कि encoding libraries, चाहे वे कितने भी अच्छे हों, हमेशा SQL "प्रोग्राम" को संशोधित करने की क्षमता रखते हैं, क्योंकि वे SQL में ही बदलाव कर रहे हैं, इससे पहले कि इसे RDBMS को भेज दिया जाए।

Parameterized queries दूसरी ओर, SQL प्रोग्राम को RDBMS में भेजें, जो तब क्वेरी का अनुकूलन करता है, क्वेरी निष्पादन योजना को परिभाषित करता है, उन अनुक्रमित अनुक्रमों का चयन करता है जिनका उपयोग किया जाना है, आदि, और फिर डेटा को प्लग करें, RDBMS के अंदर अंतिम चरण के रूप में। अपने आप।

एनकोडिंग लाइब्रेरी

  data -> (encoding library)
                  |
                  v
SQL -> (SQL + encoded data) -> RDBMS (execution plan defined) -> execute statement

परिमाणित क्वेरी

                                               data
                                                 |
                                                 v
SQL -> RDBMS (query execution plan defined) -> data -> execute statement

ऐतिहासिक महत्व

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


1
टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
maple_shaft

23
तैयार किए गए बयान एसक्यूएल इंजेक्शन हमलों से विकास का परिणाम नहीं हैं । वे शुरू से ही वहां थे। आपका प्रश्न एक झूठे आधार पर आधारित है।
user207421

4
अगर आपको लगता है कि आप बुरे लोगों से ज्यादा चालाक हैं तो # 1 के लिए जाएं
paparazzo

1
"पीक्यू पसंद का तरीका क्यों बना रहा" क्योंकि यह सबसे आसान और सबसे मजबूत है। इसके अलावा PQ के लिए उपर्युक्त प्रदर्शन लाभ। वहाँ वास्तव में एक नकारात्मक पहलू नहीं है।
पॉल ड्रेपर

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

जवाबों:


147

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

तो हाँ, उस तरह की बात SQL इंजेक्शन के हमलों को रोक देगी, लेकिन इसे लागू करना अधिक महंगा है।


60
@ डेनिस - ठीक है, आपके एसक्यूएल संस्करण में एक बोली क्या है? "? '?"? यू + 2018? \ U2018? क्या अलग-अलग अभिव्यक्तियाँ करने के गुर हैं? क्या आपकी
उपश्रेणियाँ

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

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

8
@ डेनिस मिस्टर हेनरी नल इसे सही तरीके से करने के लिए धन्यवाद देंगे।
मथिउ गुइंडन

14
@ पहला नाम अप्रासंगिक है। समस्या अंतिम नाम के साथ है। स्टैक ओवरफ्लो , प्रोग्रामर देखें। देखें , फॉक्स स्पोर्ट्स , वायर्ड , बीबीसी , और जो कुछ भी आप एक त्वरित Google खोज में बदल सकते हैं ;-)
मैथ्यू गुइंडन

80

क्योंकि विकल्प 1 कोई हल नहीं है। स्क्रीनिंग और फ़िल्टरिंग का अर्थ है अमान्य इनपुट को अस्वीकार करना या हटाना। लेकिन कोई भी इनपुट मान्य हो सकता है। उदाहरण के लिए एपोस्ट्रोफ "ओ'माली" नाम का एक वैध चरित्र है। यह सिर्फ SQL में उपयोग किए जाने से पहले सही ढंग से एन्कोड किया जाना है, जो कि तैयार स्टेटमेंट करता है।


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


2
वह यह है (और यह दो अन्य उत्तरों में लापता हिस्सा था, इसलिए +1)। यह देखते हुए कि प्रश्न कैसे बनता है, यह उपयोगकर्ता इनपुट को साफ करने के बारे में नहीं है , लेकिन, और मैं प्रश्न को उद्धृत करता हूं: "इनपुट (प्रविष्टि से पहले) फ़िल्टर करना"। यदि प्रश्न अब इनपुट को सैनिटाइज करने के बारे में है, तो आप लाइब्रेरी को ऐसा करने के बजाय इसे स्वयं क्यों करेंगे (जबकि, इसके अलावा, निष्पादन की योजना को समाप्त करने का अवसर खो देते हैं)?
आर्सेनी मूरज़ेंको

8
@ डेनिस: स्वच्छता या फ़िल्टरिंग का अर्थ है सूचना को हटाना । एन्कोडिंग का अर्थ है बिना जानकारी खोए डेटा का प्रतिनिधित्व बदलना ।
जैक्सबी

9
@ डेनिस: फ़िल्टरिंग का अर्थ है या तो उपयोगकर्ता इनपुट को स्वीकार करना या अस्वीकार करना। उदाहरण के लिए, "जेफ" को "उपयोगकर्ता की आयु" फ़ील्ड के इनपुट के रूप में फ़िल्टर किया जाएगा , क्योंकि मूल्य स्पष्ट रूप से अमान्य है। हैं, तो इनपुट को छानने के बजाय, आप के द्वारा इसे बदलने, उदाहरण के लिए, एकल उद्धरण चरित्र की जगह शुरू करते हैं, तो आप कर रहे हैं वास्तव में , जहां वे parametrized प्रश्नों का उपयोग डेटाबेस पुस्तकालयों के रूप में एक ही बात; इस मामले में, अपने प्रश्न बस है "मैं जो कुछ मौजूद है और क्षेत्र है, जब मैं हर परियोजना में पहिया बदलने सकते में विशेषज्ञों द्वारा लिखा गया था का प्रयोग करेंगे?"
Arseni Mourzenko

3
@ डेनिस: उचित प्रविष्टि (कम से कम कुछ डेटाबेस में) के लिए उद्धरण O\'Malleyसे बचने के लिए स्लैश का उपयोग कर रहा है । MS SQL या Access में इसे एक अतिरिक्त उद्धरण के साथ भगाया जा सकता है O''Malley। बहुत पोर्टेबल नहीं है अगर आपको इसे स्वयं करना है।
AbraCadaver

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

60

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

List<Integer> list = /* a list of 1, 2, 3 */
String strList = list.toString();   /* to get "[1, 2, 3]" */
strList = /* manipulate strList to become "[1, 2, 5, 3]" */
list = parseList(strList);

यदि कोई ऐसा करने का सुझाव देता है, तो आप सही तरीके से जवाब देंगे कि यह हास्यास्पद है, और यह कि बस करना चाहिए:

List<Integer> list = /* ... */;
list.add(5, position=2);

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

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

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

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

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

लिस्प मैक्रोज़ के साथ भी, आप अभी भी खराब कोड उत्पन्न कर सकते हैं, क्योंकि जरूरी नहीं कि आपको उस संरचना के बारे में पता होना चाहिए जो वहां होना चाहिए। जैसे, लिस्प में, (लेट ((अब))) a का अर्थ है "वेरिएबल a का नया लेक्सिकल बाइंडिंग a, वेरिएबल b के मान पर, और उसके बाद a का मान लौटाएँ , और (let (ab) a) का अर्थ है "वैरिएबल और बी के नए लेक्सिकल बाइंडिंग स्थापित करें और उन दोनों को एनआईएल के लिए इनिशियलाइज़ करें, और उसके बाद वैल्यू वापस करें।" वे दोनों वाक्यात्मक रूप से सही हैं, लेकिन उनका मतलब अलग-अलग चीजों से है। इस समस्या से बचने के लिए, आप अधिक शब्दार्थ कार्यों का उपयोग कर सकते हैं और ऐसा कुछ कर सकते हैं:

Variable a = new Variable("a");
Variable b = new Variable("b");
Let let = new Let();
let.getBindings().add(new LetBinding(a,b));
let.setBody(a);
return let;

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


अच्छे खर्च!
माइक पार्ट्रिज

2
आपने मुझे "अच्छी सादृश्यता" में खो दिया, लेकिन मैंने पूर्ववर्ती स्पष्टीकरण के आधार पर उत्थान किया। :)
वाइल्डकार्ड

1
बहुत बढ़िया उदाहरण! - और आप जोड़ सकते हैं: डेटाटाइप के आधार पर यह कभी-कभी संभव नहीं होता है या पार्सबल स्ट्रिंग बनाने के लिए संभव नहीं है। - क्या होगा अगर मेरा एक पैरामीटर एक स्वतंत्र पाठ क्षेत्र है जिसमें कहानी का मसौदा (~ 10.000 वर्ण) है? या क्या होगा अगर एक पैरामीटर एक JPG-Image है ? - इसके बाद एकमात्र तरीका एक पैराड्राइज्ड क्वेरी है
फाल्को

वास्तव में नहीं - यह एक बहुत बुरा विवरण है कि तैयार किए गए बयान एसक्यूएल इंजेक्शन के बचाव के रूप में क्यों विकसित हुए। विशेष रूप से दिया गया कोड उदाहरण जावा में है, जो कि उस समय के आसपास नहीं था जब पैरामीटराइज्ड क्वेरीज़ जहाँ समय सीमा में संभावना विकसित हो जाती है जहाँ C / C ++ जहां कला की स्थिति मानी जाती है। 1970-1980 के टाइमफ्रेम के शुरुआती वर्षों में एसक्यूएल डेटाबेस का उपयोग किया जाने लगा। उच्च स्तर की भाषाओं से पहले जहां लोकप्रिय थे। बिल्ली, मैं कहूंगा कि उनमें से कई डेटाबेस को आसान बनाने के लिए आए थे (पावरबुल्ट किसी को?)
टॉमटॉम

@TomTom वास्तव में, मैं आपकी अधिकांश सामग्री से सहमत हूं। मैंने केवल यहाँ सुरक्षा पहलू पर स्पष्ट रूप से छुआ है। SO पर, मैं बहुत सारे SPARQL (RDF क्वेरी भाषा, SQL के कुछ समानताओं के साथ) के प्रश्नों का उत्तर देता हूं और बहुत से लोग मुद्दों में भाग लेते हैं क्योंकि वे पैरामीटर किए गए प्रश्नों का उपयोग करने के बजाय तार को समेटते हैं। इंजेक्शन के हमलों के बिना भी, पैरामीटरकृत प्रश्न बग / क्रैश से बचने में मदद करते हैं, और बग / क्रैश सुरक्षा के मुद्दे भी हो सकते हैं, भले ही वे इंजेक्शन हमले न हों। इसलिए मैं कम और अधिक कहता हूं: पैरामीटर किए गए प्रश्न अच्छे हैं, भले ही एसक्यूएल इंजेक्शन एक मुद्दा नहीं था, और वे अच्छे हैं ...
जोशुआ टेलर

21

यह मदद करता है कि विकल्प # 2 को आम तौर पर सबसे अच्छा अभ्यास माना जाता है क्योंकि डेटाबेस क्वेरी के अनिर्धारित संस्करण को कैश कर सकता है। Parameterized क्वेरीज़ SQL इंजेक्शन के मुद्दे को कई वर्षों से मानता है (मेरा मानना ​​है), यह सिर्फ इतना होता है कि आप एक पत्थर से दो पक्षियों को मार सकते हैं।


10
SQL इंजेक्शन पहली बार आविष्कार किया गया था के बाद से SQL इंजेक्शन एक मुद्दा है। यह बाद में एक मुद्दा नहीं बना।
सेवई

9
@ सेरी सैद्धांतिक रूप से हाँ। व्यावहारिक रूप से यह केवल एक वास्तविक मुद्दा बन गया जब हमारे इनपुट तंत्र ऑनलाइन हो गए, किसी के लिए एक बड़े पैमाने पर हमले की सतह को प्रस्तुत करना।
Jan Doggen

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

5
@ मेरे ज्ञान के अनुसार, गतिशील एसक्यूएल एक अपेक्षाकृत देर से सुविधा थी; SQL का प्रारंभिक उपयोग ज्यादातर मानों (दोनों में और बाहर) के लिए मापदंडों के साथ पूर्वनिर्धारित / पूर्वनिर्मित किया गया था, इसलिए प्रश्नों में पैरामीटर सॉफ्टवेयर में SQL इंजेक्शन से पहले हो सकता है (शायद तदर्थ / सीएलआई प्रश्नों में नहीं)।
मार्क रोटटेवेल

6
वे SQL इंजेक्शन के बारे में जागरूकता का अनुमान लगा सकते हैं ।
user253751

20

सीधे शब्दों में कहा: उन्होंने नहीं किया। तुम्हारा बयान:

Parameterized Queries का उपयोग करने की दिशा में SQL Injection निवारण तंत्र क्यों विकसित हुआ?

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

मुझे याद है कि 25 साल पहले एसक्यूएल करना (जब इंटरनेट का व्यापक रूप से उपयोग नहीं किया गया था - यह बस शुरू हो रहा था) और मुझे याद है कि एसक्यूएल बनाम आईबीएम डीबी 5 आईआईआरसी संस्करण 5 - और पहले से ही पैरामीटर किए गए प्रश्न थे।


धन्यवाद। स्ट्रिंग संगति से बचने की आवश्यकता क्यों थी? मुझे ऐसा लगता है कि यह एक उपयोगी विशेषता होगी। क्या किसी के पास इसका कोई मुद्दा था?
डेनिस

3
दो वास्तव में। सबसे पहले, यह हमेशा पूरी तरह से तुच्छ नहीं है - स्मृति आवंटन आदि के साथ सौदा क्यों करें जब इसकी आवश्यकता नहीं है। लेकिन दूसरा, प्राचीन समय के प्रदर्शन में कैक्लल डेटाबेस साइड का कैशिंग बिल्कुल महान नहीं था - संकलन एसक्यूएल महंगा था। एक वर्ग तैयार कथनों (जो जहां से पैरामीटर आते हैं) का उपयोग करने के साइड इफेक्ट के रूप में, एक्साइटमेंट प्लान का पुन: उपयोग किया जा सकता है। एसक्यूएल सर्वर ने ऑटो पैरामीटराइजेशन (बिना मापदंडों के भी क्वेरी योजनाओं का पुन: उपयोग करने के लिए शुरू किया - वे काटे जाते हैं और निहित होते हैं) मुझे लगता है कि 2000 या 2007 - कहीं न कहीं, IIRC।
टॉमटॉम

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

हां, लेकिन जैसा कि मैंने कहा - जब वे आविष्कार किए गए थे, तब तक गतिशील एसक्यूएल काफी सभ्य प्रदर्शन के साथ आया था;) आज भी लोग आपको बताते हैं कि एसक्यूएल सर्वर में डायनेमिक एसक्यूएल क्वेरी योजना का पुन: उपयोग नहीं किया जाता है (जो कि गलत है - एचएम - जैसे मैंने २००० और २०० long के बीच कुछ बिंदु कहा - इतनी लंबी)। यदि आप कई बार sql चलाते हैं तो उस पुराने समय में आप वास्तव में पूर्व-निर्धारित कथन चाहते थे;)
TomTom

गतिशील SQL के लिए योजना कैशिंग वास्तव में SQL Server 7.0 में जोड़ा गया था, 1998 में - sqlmag.com/database-performance-tuning/…
माइक

13

अन्य सभी अच्छे उत्तरों के अलावा:

# 2 का कारण बेहतर है क्योंकि यह आपके डेटा को आपसे अलग करता है। # 1 में आपका डेटा आपके कोड का हिस्सा है और यहीं से सारी बुरी चीजें आती हैं। # 1 के साथ आपको अपनी क्वेरी मिलती है और यह सुनिश्चित करने के लिए अतिरिक्त चरणों को करने की आवश्यकता होती है कि आपकी क्वेरी आपके डेटा को डेटा समझती है जबकि # 2 में आपको अपना कोड मिलता है और यह कोड है और आपका डेटा डेटा है।


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

11

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

SQL डेटाबेस के दृष्टिकोण से select * from employees where last_name = 'Smith'और select * from employees where last_name = 'Fisher'विशिष्ट रूप से अलग हैं और इसलिए अलग पार्सिंग, संकलन और अनुकूलन की आवश्यकता होती है। वे संकलित कथनों के लिए समर्पित मेमोरी क्षेत्र में अलग-अलग स्लॉट पर भी कब्जा कर लेंगे। बड़ी संख्या में समान प्रश्नों के साथ एक भारी भरकम प्रणाली में विभिन्न मापदंडों की गणना और मेमोरी ओवरहेड पर्याप्त हो सकते हैं।

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


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

निम्न प्रश्न SQL पार्सर के लिए भी अलग हैं: SELECT * FROM employees WHERE last_name IN (?, ?)और SELECT * FROM employees WHERE last_name IN (?, ?, ?, ?, ?, ?)
डेमियन यरिक

हाँ उनके पास है। ऐसा क्यों है कि MS ने क्वेरी प्लान कैशिंग को 1998 में SQL Server 7 में जोड़ा। जैसा कि: आपकी जानकारी एक पीढ़ी पुरानी है।
टॉमटॉम

1
@TomTom - क्वेरी प्लान कैशिंग ऑटो-पैरामीटराइजेशन के समान नहीं है, जिस पर आप संकेत देते हैं। जैसा कि, आप पोस्ट करने से पहले पढ़ें।
18-29 में 18

@mustaccio वास्तव में कम से कम एमएस ने एक ही समय में दोनों का परिचय दिया।
TomTom

5

रुको लेकिन क्यों?

विकल्प 1 का अर्थ है कि आपको किसी भी प्रकार के इनपुट के लिए सैनिटाइज़िंग रूटीन लिखना होगा जबकि विकल्प 2 आपके लिए लिखने / परीक्षण करने / बनाए रखने के लिए कम त्रुटि वाला और कम कोड है।

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

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


1
JDBC एंथिंग को पवित्र नहीं करता है। प्रोटोकॉल में पैरामीटर के लिए विशिष्ट भाग होता है और DB बस उस पैरामीटर की व्याख्या नहीं करता है। यही कारण है कि आप पैरामीटर से टेबल का नाम सेट कर सकते हैं।
कथा

1
क्यों? अगर पैरामीटर को पार्स नहीं किया गया है या व्याख्या नहीं की गई है तो कुछ बचने का कोई कारण नहीं है।
कथा

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

2
@IMSoP यह मेरी एक गलत धारणा थी। हालाँकि मुझे लगता है कि यह एक सामान्य बात है क्योंकि आप इस सवाल के दो सबसे अधिक वोट किए गए उत्तरों को SO stackoverflow.com/questions/3271249/… में देख सकते हैं । मैं इसके बारे में पढ़ता हूं और आप सही हैं। मैंने उत्तर संपादित किया।
ट्यूलेंस कोरडोवा

3
@TomTom प्रदर्शन के लिए बहुत अच्छा है , लेकिन यह सुरक्षा के लिए कुछ नहीं करता है । जब तक गतिशील एसक्यूएल का एक संकलित टुकड़ा संकलित और कैश नहीं किया जाता है, तब तक कार्यक्रम पहले ही बदल दिया गया है । गैर-गतिशील पैरामीटराइज़्ड SQL से एक योजना बनाना और फिर डेटा तत्वों को पास करना अभी भी मूल रूप से एक DBMS से अलग है जो दो प्रश्नों के बीच समानता को पूरा SQL स्ट्रिंग्स के रूप में प्रस्तुत करता है।
IMSoP

1

आइए कल्पना करें कि एक आदर्श "स्वच्छता, फ़िल्टर और एनकोड" दृष्टिकोण कैसा दिखेगा।

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

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

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

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

इस बिंदु पर, हमने केवल पैरामीटर किए गए प्रश्नों को पुनर्निमित किया है।

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

एन्कोडिंग सही करने के लिए कठिन है, और एन्कोडिंग-किया-राइट पैरामीटरमीशन से अप्रभेद्य है।

यदि आप वास्तव में स्ट्रिंग इंटरपोलेशन को बिल्डिंग क्वेश्चन के रूप में पसंद करते हैं, तो कुछ भाषाएँ हैं (स्काला और ES2015 दिमाग में आती हैं) जिसमें प्लग करने योग्य स्ट्रिंग इंटरपोलेशन होते हैं, इसलिए ऐसी लाइब्रेरीज़ होती हैं , जो आपको ऐसे स्टै्रंड इंटरपोलेशन के रूप में दिखने वाले पैरामीटर वाले प्रश्न लिखने देती हैं, लेकिन SQL इंजेक्शन से सुरक्षित हैं - इसलिए ES2015 सिंटैक्स में:

import {sql} from 'cool-sql-library'

let result = sql`select *
    from users
    where user_id = ${user_id}
      and password_hash = ${password_hash}`.execute()

console.log(result)

1
"एन्कोडिंग सही करना कठिन है" - हाहाहा। यह नहीं। एक या दो दिन, यह सब प्रलेखित है। मैंने एक ORM के लिए कई साल पहले एक एनकोडर लिखा था (क्योंकि sql सर्वर की मापदंडों पर एक सीमा है और इस प्रकार एक बयान में 5000-10000 पंक्तियों को सम्मिलित करना समस्या है (15 साल पहले)। मुझे याद नहीं है कि एक बड़ी समस्या है।
टॉमटॉम

1
शायद SQL सर्वर पर्याप्त रूप से नियमित है कि यह एक गैर-समस्या है, लेकिन मुझे अन्य DBs में समस्याओं का सामना करना पड़ा है - बेमेल चरित्र एन्कोडिंग, अस्पष्ट कॉन्फ़िगरेशन विकल्प, स्थानीय विशिष्ट दिनांक और संख्या समस्याओं के साथ कोने के मामले। सभी सॉल्वेबल, लेकिन कम से कम डीबी के क्विर्क (मैं आपको, MySQL और ओरेकल को देख रहा हूं) पर एक सरसरी समझ की जरूरत है।
जेम्स_पिक

3
@TomTom एन्कोडिंग वास्तव में बहुत मुश्किल है एक बार जब आप समय में कारक प्राप्त करते हैं। जब आपका डीबी विक्रेता अगली रिलीज में एक नई टिप्पणी शैली बनाने का फैसला करता है या जब एक उन्नयन में एक नया कीवर्ड बन जाता है तो आप क्या करते हैं? आप सैद्धांतिक रूप से अपने RDBMS के एक रिलीज के लिए वास्तव में एन्कोडिंग प्राप्त कर सकते हैं और अगले संशोधन पर गलत हो सकते हैं। जब आप वेंडर को नॉन-सिंटैक्स सिचुएशन का उपयोग करने वाली सशर्त टिप्पणियों के
एरिक

@ एरिक, यह स्पष्ट रूप से भयानक है। (मैं Postgres का उपयोग करें; अगर यह किसी भी ऐसे विचित्र मौसा मैं अभी तक उनका सामना करने के लिए है।)
वाइल्डकार्ड

0

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

  1. [ सभी सुरक्षित एसक्यूएल प्रश्नों ] के लिए [ इन्फिनिटी ] सावधानीपूर्वक स्क्रीनिंग और फ़िल्टरिंग
  2. [ अपने दायरे तक सीमित पूर्वनिर्धारित परिदृश्यों ] का उपयोग करना

अन्य उत्तरों के अनुसार, आपके कार्यक्षेत्र को अनंत से दूर रखने और कुछ प्रबंधनीय की ओर कुछ प्रदर्शन लाभ भी प्रतीत होते हैं।


0

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

एक SQL इंजेक्शन भेद्यता सी। की तरह एक भाषा में एक बफर अतिप्रवाह करने के लिए isomorphic है। इतिहास से पता चला है कि बफर overflows को रोकने के लिए बेहद मुश्किल है - यहां तक ​​कि समीक्षा के लिए अत्यंत महत्वपूर्ण कोड भी अक्सर ऐसी कमजोरियों को समाहित करता है।

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

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

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


यह सब अच्छा और बांका है, लेकिन यह सवाल को शीर्षक के अनुसार बिल्कुल भी संबोधित नहीं करता है।
टॉमटॉम

1
@TomTom: आपका क्या मतलब है? प्रश्न बिल्कुल इस बारे में है कि एसक्यूएल इंजेक्शन को रोकने के लिए पैरामीटरयुक्त प्रश्न पसंदीदा तंत्र क्यों हैं; मेरा उत्तर बताता है कि उपयोगकर्ता इनपुट सेिटेटिंग की तुलना में पैरामीटराइज्ड क्वेश्चन अधिक सुरक्षित और मजबूत क्यों हैं।
डेनियल प्रेडेन

मुझे खेद है, लेकिन मेरा सवाल है "एसक्यूएल इंजेक्शन रोकथाम तंत्र क्यों परिमित क्वेरीज़ का उपयोग करने की दिशा में विकसित हुआ?"। उन्होंने नहीं किया। यह अब के बारे में नहीं है, यह इतिहास के बारे में है।
TomTom

0

मैं इसके बारे में यहाँ लिखता हूँ: https://stackoverflow.com/questions/6786034/can-parameterized-statement-stop-all-sql-injection/33033576#33033576

लेकिन, बस इसे सरल रखने के लिए:

जिस तरह से क्वेरीज़ काम करती है, वह यह है कि sqlQuery को एक क्वेरी के रूप में भेजा जाता है, और डेटाबेस को ठीक से पता है कि यह क्वेरी क्या करेगी, और उसके बाद ही यह उपयोगकर्ता नाम और पासवर्ड को केवल मान के रूप में सम्मिलित करेगा। इसका मतलब है कि वे क्वेरी को प्रभावित नहीं कर सकते, क्योंकि डेटाबेस पहले से ही जानता है कि क्वेरी क्या करेगी। तो इस मामले में यह "Nobody OR 1 = 1 '-" का एक उपयोगकर्ता नाम और एक रिक्त पासवर्ड होगा, जो कि गलत होना चाहिए।

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


0

मैंने कभी SQL का उपयोग नहीं किया है। लेकिन स्पष्ट रूप से आप इस बारे में सुनते हैं कि लोगों को क्या समस्या है, और SQL डेवलपर्स को इस "SQL इंजेक्शन" चीज़ से समस्या थी। लंबे समय तक मैं इसका पता नहीं लगा सका। और फिर मुझे एहसास हुआ कि लोग जहां एसक्यूएल स्टेटमेंट बनाते हैं, वास्तविक टेक्सुअल एसक्यूएल सोर्स स्टेटमेंट, स्ट्रिंग्स को समेट कर, जिनमें से कुछ उपयोगकर्ता द्वारा दर्ज किए जाते हैं। और उस अहसास पर मेरा पहला विचार झटका था। कुल झटका। मैंने सोचा: किसी को भी इतनी हास्यास्पद रूप से बेवकूफ कैसे बनाया जा सकता है और किसी भी प्रोग्रामिंग भाषा में बयान दे सकता है? C, या C ++, या Java, या Swift डेवलपर के लिए, यह बिलकुल पागलपन है।

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

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

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

इसलिए संकलित भाषाओं का उपयोग करने वाले एक डेवलपर के दृष्टिकोण से, स्वच्छता एक ऐसी चीज है जो मेरे लिए कभी नहीं होगी। स्वच्छता की आवश्यकता पागल है। पैरामीटरकृत समस्याएँ समस्या का स्पष्ट समाधान हैं।

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


-2

मुख्य समस्या यह है कि हैकर्स ने स्वच्छता को घेरने के तरीके ढूंढे, जबकि पैराड्राइज्ड प्रश्न एक मौजूदा प्रक्रिया थी जो प्रदर्शन और स्मृति के अतिरिक्त लाभों के साथ पूरी तरह से काम करती थी।

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

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

दूसरी ओर, केवल संक्षिप्त प्रश्नों का उपयोग करना और उसका उपयोग करना सीखने की बात थी।

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