क्या पैरामीटर स्टेटमेंट सभी एसक्यूएल इंजेक्शन को रोक सकता है?


80

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


6
यह एक महान सवाल है, बिल्कुल भयानक जवाबों के साथ (जैसा कि मैं टिप्पणी कर रहा हूं)
Ibu

मैं किसी को कम से कम 15k प्रतिष्ठा के साथ या अच्छे अनुभव के साथ इस सवाल में मूल्यवान इनपुट जोड़ सकता हूं।
इबू जूल

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

2
इसी तरह के सवालों के बिल करविन के कुछ जवाब भी देखें : SQL इंजेक्शन क्या है?
माइक

जवाबों:


66

मैंने अपनी टिप्पणियों में प्रश्न के लिए जो लिंक पोस्ट किए हैं वे समस्या को बहुत अच्छी तरह से समझाते हैं। मैंने अपनी भावनाओं को संक्षेप में बताया है कि समस्या क्यों बनी हुई है:

  1. बस शुरू करने वालों को SQL इंजेक्शन के बारे में कोई जानकारी नहीं हो सकती है।

  2. कुछ लोग SQL इंजेक्शन के बारे में जानते हैं, लेकिन सोचते हैं कि बचना ही (केवल?) समाधान है। यदि आप एक त्वरित Google खोज करते हैं php mysql query, तो जो पहला पृष्ठ दिखाई देता है वह mysql_queryपृष्ठ है, जिस पर एक उदाहरण है जो एक इनपुट में भागे हुए उपयोगकर्ता इनपुट को इंटरपोलिंग दिखाता है। इसके बजाय तैयार बयानों का उपयोग करने का कोई उल्लेख नहीं है (कम से कम ऐसा नहीं है कि मैं देख सकता हूं)। जैसा कि दूसरों ने कहा है, वहाँ बहुत सारे ट्यूटोरियल हैं जो पैरामीटर प्रक्षेप का उपयोग करते हैं, कि यह वास्तव में आश्चर्यजनक नहीं है कि यह अभी भी कितनी बार उपयोग किया जाता है।

  3. कैसे मानकीकृत बयान काम करते हैं, यह समझने की कमी है। कुछ लोग सोचते हैं कि यह मूल्यों से बचने का सिर्फ एक फैंसी साधन है।

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

  5. कुछ हर जगह पैरामीटर स्टेटमेंट का उपयोग करते हैं, लेकिन टेबल और कॉलम के नाम, कीवर्ड और सशर्त ऑपरेटरों जैसे अनियंत्रित मूल्यों के प्रक्षेप के साथ। डायनामिक खोज, जैसे कि जो उपयोगकर्ताओं को कई अलग-अलग खोज फ़ील्ड निर्दिष्ट करने की अनुमति देती हैं, तुलना की स्थिति और क्रम क्रम, इसके प्रमुख उदाहरण हैं।

  6. ORM का उपयोग करते समय सुरक्षा की गलत समझ। ORM अभी भी SQL कथन भागों के प्रक्षेप की अनुमति देते हैं - 5 देखें।

  7. प्रोग्रामिंग एक बड़ा और जटिल विषय है, डेटाबेस प्रबंधन एक बड़ा और जटिल विषय है, सुरक्षा एक बड़ा और जटिल विषय है। एक सुरक्षित डेटाबेस एप्लिकेशन विकसित करना आसान नहीं है - यहां तक ​​कि अनुभवी डेवलपर्स को भी पकड़ा जा सकता है।

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


65

जब लेख एसक्यूएल हमलों को रोकने के लिए पैरामीटरयुक्त प्रश्नों के बारे में बात करते हैं, तो वे वास्तव में यह नहीं समझाते हैं कि, यह अक्सर "ऐसा करता है, इसलिए यह मत पूछें" - संभवतः क्योंकि वे खुद को नहीं जानते हैं। एक बुरे शिक्षक का एक निश्चित संकेत यह है कि वे स्वीकार नहीं कर सकते कि वे कुछ नहीं जानते हैं। लेकिन मैं पीछे हटा। जब मैं कहता हूं कि मैंने पाया कि भ्रमित होना पूरी तरह से सरल है। एक गतिशील SQL क्वेरी की कल्पना करें

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password

इतना आसान sql इंजेक्शन सिर्फ 'या 1 = 1-- के रूप में यूजरनेम लगाने के लिए होगा। यह प्रभावी रूप से sql क्वेरी बना देगा:

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password

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

अब मानकीकृत प्रश्न इसे अलग तरह से करते हैं, जैसे कोड:

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?'

parameters.add("User", username)
parameters.add("Pass", password)

जहां उपयोगकर्ता नाम और पासवर्ड संबंधित इनपुट किए गए उपयोगकर्ता नाम और पासवर्ड की ओर इशारा करते हैं

अब इस बिंदु पर, आप सोच रहे होंगे, यह कुछ भी नहीं बदलता है। निश्चित रूप से आप अभी भी उपयोगकर्ता नाम फ़ील्ड में कुछ भी नहीं डाल सकते हैं जैसे कोई भी या 1 = 1 '-, प्रभावी रूप से क्वेरी बना रहा है:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'

और यह एक मान्य तर्क की तरह प्रतीत होगा। लेकिन तुम्हारी बात गलत सिद्ध होगी।

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

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


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

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

प्रतिभाशाली। एक उदाहरण के रूप में वे कहते हैं एक हजार शब्द पेंट!
Drenai

10

अच्छा सवाल है। उत्तर निर्धारक की तुलना में अधिक स्टोचस्टिक है और मैं एक छोटे से उदाहरण का उपयोग करते हुए अपने दृष्टिकोण को समझाने की कोशिश करूंगा।

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

निम्न SQL सर्वर संग्रहित प्रक्रिया पर विचार करें जो तालिका 'उपयोगकर्ता' से उपयोगकर्ता पंक्ति प्राप्त करेगी:

create procedure getUser
 @name varchar(20)
,@pass varchar(20)
as
declare @sql as nvarchar(512)
set @sql = 'select usrID, usrUName, usrFullName, usrRoleID '+
           'from Users '+
           'where usrUName = '''+@name+''' and usrPass = '''+@pass+''''
execute(@sql)

आप उपयोगकर्ता नाम और पासवर्ड पैरामीटर के रूप में पास करके परिणाम प्राप्त कर सकते हैं। पासवर्ड को मुफ़्त पाठ में मान लेना (केवल इस उदाहरण की सादगी के लिए) एक सामान्य कॉल होगी:

DECLARE @RC int
DECLARE @name varchar(20)
DECLARE @pass varchar(20)

EXECUTE @RC = [dbo].[getUser] 
   @name = 'admin'
  ,@pass = '!@Th1siSTheP@ssw0rd!!'
GO

लेकिन यहां हमारे पास प्रोग्रामर द्वारा संग्रहीत प्रक्रिया के अंदर उपयोग की जाने वाली एक खराब प्रोग्रामिंग तकनीक है, इसलिए एक हमलावर निम्नलिखित को निष्पादित कर सकता है:

DECLARE @RC int
DECLARE @name varchar(20)
DECLARE @pass varchar(20)

EXECUTE @RC = [TestDB].[dbo].[getUser] 
   @name = 'admin'
  ,@pass = 'any'' OR 1=1 --'
GO

उपरोक्त मापदंडों को संग्रहीत प्रक्रिया के तर्क के रूप में पारित किया जाएगा और SQL कमांड जिसे अंततः निष्पादित किया जाएगा:

select usrID, usrUName, usrFullName, usrRoleID 
from Users 
where usrUName = 'admin' and usrPass = 'any' OR 1=1 --'

.. जो उपयोगकर्ताओं से सभी पंक्तियों को वापस मिलेगा

यहां समस्या यह है कि यहां तक ​​कि हम उस सिद्धांत का पालन करते हैं "एक संग्रहीत प्रक्रिया बनाएं और मापदंडों के रूप में खोज करने के लिए फ़ील्ड पास करें" एसक्यूआई अभी भी किया जाता है। ऐसा इसलिए है क्योंकि हम अपनी खराब प्रोग्रामिंग प्रैक्टिस को सिर्फ स्टोर की गई प्रक्रिया के अंदर कॉपी करते हैं। समस्या का समाधान हमारी संग्रहित प्रक्रिया को फिर से लिखना है:

alter procedure getUser
 @name varchar(20)
,@pass varchar(20)
as
select usrID, usrUName, usrFullName, usrRoleID 
from Users 
where usrUName = @name and usrPass = @pass

मैं जो कहना चाह रहा हूं, वह यह है कि डेवलपर्स को पहले यह सीखना चाहिए कि SQLi अटैक क्या है और कैसे किया जा सकता है और फिर उसी के अनुसार अपने कोड को सुरक्षित रखना है। नेत्रहीन रूप से 'सर्वोत्तम प्रथाओं' का पालन करना हमेशा सुरक्षित तरीका नहीं होता है ... और शायद इसीलिए हमारे पास बहुत सारी 'सर्वोत्तम प्रथाएँ' हैं- असफलताएँ!


मैं आपकी बात समझ सकता हूं और मैं इसका दोषी हूं। कभी-कभी गतिशील एसक्यूएल क्वेरी निर्माण की आवश्यकता होती है जो मैंने मापदंडों के संयोजन का उपयोग किया था। आप कैसे सुझाव देंगे कि मैं इसके बारे में जाऊँ?
theProvost

@ यह एक अच्छा सवाल है। Sp_executesql पर विचार करें: msdn.microsoft.com/en-us/library/ms188001.aspx
Tim

@ टिम हाय टिम। Im गतिशील गतिशील करने के लिए नया। Sp_executesql और EXECUTE (@SqlQuery) में क्या अंतर है
TheProvost

2
मुझे लगता है कि यह पोस्ट एक सरल उदाहरण को अच्छी तरह से समझाता है: codeproject.com/Tips/586207/… - लेकिन मूल रूप से, EXECUTE (@SqlQuery) एसक्यूएल इंजेक्शन को रोकने के लिए कुछ नहीं करता है, हालांकि sp_executesql (@SllQuery, ..., ...) इसे रोकता है। Microsoft आलेख में उदाहरणों की मदद करनी चाहिए।
टिम

टिम के पास समाधान TheProvost ...;) आप एक गतिशील SQL मामले के लिए sp_executesql (@QUERY, @PARAMETERS, @VARS) ... का उपयोग कर सकते हैं ...
Andreas Venieris

5

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

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

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

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


1
लिंक किए गए उत्तर का वास्तव में तैयार किए गए कथनों से कोई लेना-देना नहीं है।
आपका कॉमन सेंस

1
@YourCommonSense: यह पैरामीटर किए गए प्रश्नों के बारे में है, वे वास्तविक रूप से तैयार नहीं हो सकते हैं लेकिन उपयोग किए गए ड्राइवर के आधार पर अनुकरण किए जाते हैं। यह जानना महत्वपूर्ण है और बहुत जुड़ा हुआ है ...
kelunik

1
उसी पृष्ठ के अन्य उत्तर में एक बहुत अच्छी टिप्पणी है: "यदि आपके सभी प्रश्न पैराट्राइज्ड हैं, तो आप 2nd ऑर्डर इंजेक्शन से भी सुरक्षित हैं। पहला ऑर्डर इंजेक्शन यह भूल रहा है कि उपयोगकर्ता डेटा अविश्वसनीय है। 2 डी इंजेक्शन इंजेक्शन उस डेटाबेस डेटा को भूल रहा है। अविश्वास (क्योंकि यह मूल रूप से उपयोगकर्ता से आया था)। "
रॉड्रिगो

@kelunik लिंक किए गए उत्तर पैरामीटर वाले प्रश्नों के बारे में नहीं है, यह एक पुस्तकालय के बारे में है जो अनिवार्य रूप से उन्हें बनाता है। एक पैरामीटरकृत क्वेरी वह है जो सर्वर पर अलग-अलग पैरामीटर मानों के साथ भेजी जाती है।
पनगोटियोटिस कानावोस

@PanagiotisKanavos: मैं उस उत्तर की सामग्री को अच्छी तरह जानता हूँ। यह सिर्फ एक उदाहरण है (और एक बहुत ही सामान्य है) कि आपके द्वारा उपयोग किए जाने वाले पैरामीटर वाले प्रश्नों को वास्तव में तैयार किए गए कथनों के रूप में लागू नहीं किया जा सकता है ...
kelunik

3

मैं प्रोग्रामिंग में निरपेक्षता से बचता हूं; हमेशा एक अपवाद होता है। मैं संग्रहीत प्रक्रियाओं और कमांड ऑब्जेक्ट्स की अत्यधिक अनुशंसा करता हूं। मेरे बैक ग्राउंड का अधिकांश हिस्सा SQL सर्वर के साथ है, लेकिन मैं समय-समय पर MySql के साथ खेलता हूं। कैश्ड क्वेरी योजनाओं सहित संग्रहीत कार्यविधियों के कई फायदे हैं; हां, यह मापदंडों और इनलाइन SQL के साथ पूरा किया जा सकता है, लेकिन यह इंजेक्शन हमलों के लिए अधिक संभावनाएं खोलता है और चिंताओं को अलग करने में मदद नहीं करता है। मेरे लिए डेटाबेस को सुरक्षित करना भी बहुत आसान है क्योंकि मेरे आवेदन में आमतौर पर केवल उक्त संग्रहीत प्रक्रियाओं के लिए अनुमति होती है। प्रत्यक्ष तालिका / दृश्य पहुंच के बिना कुछ भी इंजेक्षन करना अधिक कठिन है। यदि उपयोगकर्ता से छेड़छाड़ की जाती है, तो केवल उसी को निष्पादित करने की अनुमति होती है, जो पहले से परिभाषित था।

मेरे दो सेंट।


यह प्रश्न से कैसे संबंधित है? आप संग्रहीत कार्यविधियों को पैरामीटर कैसे कॉल और पास करने जा रहे हैं? स्ट्रिंग संघनन का उपयोग करके या एक पैरामीटर क्वेरी का उपयोग करके? इसके अलावा - क्या होगा अगर कोई "डायनामिक" क्वेरी बनाने के लिए संग्रहीत कार्यविधि के अंदर स्ट्रिंग कॉन्सेन्टेशन का उपयोग करता है ? सिर्फ इसलिए कि यह एक संग्रहित प्रक्रिया है इसका मतलब यह नहीं है कि यह सुरक्षित है
पनगियोटिस कानवास

आम तौर पर मैं एक कमांड ऑब्जेक्ट का उपयोग करता हूं और मैं डिजाइन द्वारा "डायनेमिक क्वेरी" चलाने से भी बचता हूं।
डेरेक

2

मैं "गूंगा" नहीं कहूंगा।

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


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

2

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


2

क्या पैरामीटर स्टेटमेंट सभी एसक्यूएल इंजेक्शन को रोक सकता है?

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

यही कारण है कि मैंने PHP के लिए अपना मैसूरल रैपर बनाया है जो क्वेरी और डायनॉजिस्ट सहित गतिशील रूप से क्वेरी में जोड़े जा सकने वाले अधिकांश शाब्दिक समर्थन करता है।

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

जैसा कि आप देख सकते हैं, वास्तव में आपके सभी प्रश्नों को मानकीकृत करना असंभव है , भले ही आप गूंगे न हों।


यदि आपके सभी प्रश्नों को परिचालित किया जाता है (वे उपयोगकर्ता डेटा या आपके डेटाबेस डेटा से आते हैं), तो ऐसा लगता है कि आप सुरक्षित हैं, जैसा कि यहां सबसे अधिक टिप्पणी में कहा गया है: stackoverflow.com/a/134138/1086511
रोड्रिगो

मैंने आपकी राय मांगी, सिर्फ इसलिए कि आप काफी उचित लग रहे थे। मुझे नहीं लगता कि अगर मैंने कहीं और पढ़ा है तो आपका तरीका सबसे अच्छा होगा। वैसे भी, अगर आपको "नियमित साधनों के साथ आप अपने सभी प्रश्नों को मानकीकृत नहीं कर सकते हैं" में सुधार करते हैं तो मुझे अच्छा लगेगा।
रोड्रिगो

मैंने आपका जवाब पढ़ना शुरू कर दिया, जब तक मुझे "एसक्यूएल शाब्दिक" की पहचान करने का विचार नहीं मिला। यह विचार मुझे बिलकुल सही नहीं लगा (यह ओवरजॉब लग रहा था)। यदि यह सच है कि पैरामीटरयुक्त प्रश्न PHP में इंजेक्शन से बच रहे हैं (मैं अभी भी शोध कर रहा हूं), तो मेरा अगला कदम जावास्क्रिप्ट इंजेक्शन से बचना है। फिर, मैं आपके समाधान का अध्ययन करने के लिए वापस आऊंगा। इसके अलावा, मैं पोस्टग्रेज का उपयोग कर रहा हूं, और शायद आपका समाधान mysql विशिष्ट है?
रोड्रिगो

ठीक है, अब मैं इसे (फिर से) पढ़ता हूं, और यह मत सोचो कि "आपके सभी प्रश्नों को मानकीकृत करना असंभव है" एक सुधार है। क्या MySQL में यह असंभव है? क्या यह असंभव भी है PostgreSQL में? क्यों? क्या मेरी php स्क्रिप्ट के बाहर कोई क्वेरी है? कहाँ पे? मुझे लगता है कि पहचानकर्ता से आपका मतलब एक आरक्षित शब्द है, जिसे आप अपने $ _POST सरणी से छीनने की कोशिश करते हैं? यह मुझे (सहज रूप से, मैं गलत हो सकता है) जाने का रास्ता नहीं लगता। इसके अलावा, मुझे समझ नहीं आया कि "क्या आपने इसे कभी बांधने की कोशिश की?" क्या बांधें?
रोड्रिगो

जैसा कि मैंने सोचा था कि वेब पर खोजना इतना आसान नहीं है। यदि आप कर सकते हैं तो एक संदर्भ जोड़ें।
रॉड्रिगो

2

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

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

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

यह कुछ अधिक काम है (और कार्यक्रम के लिए इतना सीधा नहीं) विशेष रूप से कुछ "त्वरित और गंदे" नौकरियों के लिए जो अक्सर बहुत बड़े-बड़े साबित होते हैं ...

सादर,

डिब्बा


2

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

कुछ विशिष्ट मामलों में, यह पर्याप्त नहीं है। कई DBMSes में, DBMS स्तर पर SQL इंजेक्शन दोष का परिचय देते हुए, SQL को संग्रहीत प्रक्रियाओं के साथ गतिशील रूप से निष्पादित करना संभव है। पैरामीटर किए गए प्रश्नों का उपयोग करके ऐसी संग्रहीत प्रक्रिया को कॉल करने से प्रक्रिया में SQL इंजेक्शन को शोषण होने से नहीं रोका जा सकेगा। एक और उदाहरण इस ब्लॉग पोस्ट में देखा जा सकता है ।

अधिक सामान्यतः, डेवलपर्स गलत तरीके से कार्यक्षमता का उपयोग करते हैं। आमतौर पर कोड कुछ ऐसा दिखता है जब सही तरीके से किया जाता है:

db.parameterize_query("select foo from bar where baz = '?'", user_input)

कुछ डेवलपर्स एक साथ तारों को समतल करेंगे और फिर एक पैरामीटर क्वेरी का उपयोग करेंगे, जो वास्तव में उपरोक्त डेटा / कोड भेद नहीं करता है जो हमें सुरक्षा गारंटी प्रदान करता है:

db.parameterize_query("select foo from bar where baz = '" + user_input + "'")

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


1

अपने एप्लिकेशन को SQL इंजेक्शन से बचाने के लिए, निम्न चरणों का पालन करें:

चरण 1. बाधा इनपुट। चरण 2. संग्रहीत प्रक्रियाओं के साथ मापदंडों का उपयोग करें। चरण 3. गतिशील एसक्यूएल के साथ मापदंडों का उपयोग करें।

Http://msdn.microsoft.com/en-us/library/ff648339.aspx का संदर्भ लें


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

@ फ़ाहाद मैं # 2 को "प्रश्नों में और संग्रहीत कार्यविधियों में मानकीकृत कथनों का उपयोग कर सकता हूँ" के रूप में पुन: प्रस्तुत कर सकता है। +1 से नोवेलोक्रेट की टिप्पणी कि मापदंडों के बिना संग्रहीत प्रक्रियाओं का उपयोग करने से आपको बहुत कुछ नहीं मिलता है।
मैथ्यू

1

भले ही तैयार किए गए बयानों का उपयोग वेब एप्लिकेशन के अपने कोड में ठीक से किया गया हो, यदि SQL कोड घटक असुरक्षित तरीके से उपयोगकर्ता इनपुट से क्वेरी का निर्माण करते हैं, तो SQL इंजेक्शन की खामियां अभी भी मौजूद हो सकती हैं। निम्न संग्रहीत कार्यविधि का एक उदाहरण है जो @name पैरामीटर में SQL इंजेक्शन के लिए असुरक्षित है:

CREATE PROCEDURE show_current_orders
(@name varchar(400) = NULL)
AS
DECLARE @sql nvarchar(4000)
SELECT @sql = ‘SELECT id_num, searchstring FROM searchorders WHERE ‘ +
‘searchstring = ‘’’ + @name + ‘’’’;
EXEC (@sql)
GO

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

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