क्या हमें इंजेक्शन के हमलों से बचाने के लिए अभी भी QUOTENAME का उपयोग करना चाहिए?


9

मैं आज एक पुरानी संग्रहित प्रक्रिया को देख रहा था और देखा कि यह quotenameइनपुट मापदंडों पर उपयोग कर रहा है । कुछ खुदाई करने के बाद यह पता लगाने के लिए कि इस साइट पर वास्तव में क्या हुआ है । अब मैं समझता हूं कि यह क्या करता है और इसका उपयोग कैसे किया जाता है, लेकिन साइट का कहना है कि इसका उपयोग SQL इंजेक्शन हमलों से शमन के रूप में किया जाता है। जब मैं ऐसे ऐप्स विकसित करता था जो सीधे asp.net का उपयोग करते हुए एक डेटाबेस को क्वेरी करता था, तो मैं ADO.Net पैरामीटर का उपयोग उपयोगकर्ता इनपुट को शाब्दिक मान के रूप में पास करने के लिए करता था और कभी भी मेरी संग्रहीत प्रक्रियाओं में इसे बचाने के बारे में चिंतित नहीं था।

मैं अब एक संग्रहीत प्रक्रिया लिख ​​रहा हूं जिसका उपयोग उन अनुप्रयोगों द्वारा किया जाएगा जो मैं नहीं लिखता हूं इसलिए मुझे प्रक्रिया स्तर पर इंजेक्शन के हमलों से quotenameबचने और बचाव करने की आवश्यकता है, यह करने का सबसे अच्छा तरीका है या एक नया कार्य है / बेहतर तरीका?

इस विचार पद्धति पर मुझे मिला कोड ( @parm1एक उपयोगकर्ता इनपुट पैरामीटर है):

'SELECT project [Project], project_desc [Description], 
        customer [Customer], cpnyid [Company]
FROM PJPROJ (nolock)
where project like ' + quotename(@parm1,'''') + '

जवाबों:


17

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

फ़ंक्शन केवल ऑब्जेक्ट नामों (जैसे तालिका, स्तंभ, डेटाबेस नाम) के लिए उपयुक्त है।

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

इस विषय पर निश्चित लेख अभी भी गतिशील एसक्यूएल के अभिशाप और आशीर्वाद है


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

इसके अतिरिक्त यह अभी भी SQL इंजेक्शन संभावनाओं को छोड़ सकता है यदि स्ट्रिंग में मानक एपोस्ट्रोफ के बजाय U + 02BC शामिल है और फिर स्वच्छता के बाद स्ट्रिंग को एक varchar को सौंपा गया है ( जहां यह चुपचाप एक नियमित एपोस्ट्रोफ में परिवर्तित हो सकता है )

ऐसा करने का सही तरीका क्वेरीज़ को छोड़ दिया गया है। और फिर में @parm1मान पास करेंsys.sp_executesql

DECLARE @Sql NVARCHAR(MAX);

SET @Sql = '
SELECT project      [Project],
       project_desc [Description],
       customer     [Customer],
       cpnyid       [Company]
FROM   PJPROJ (nolock)
WHERE  project LIKE @parm1 
';

EXEC sys.sp_executesql
  @Sql,
  N'@parm1 varchar(100)',
  @parm1 = 'foobar%'; 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.