2009-04-01 11 views
7

तर्क के लिए, आइए बस यह कहें कि को को स्थानीय चर बनाने वाला एक SQL क्वेरी है जिसमें एक INSERT है:एसक्यूएल सर्वर: इंजेक्शन हमलों के खिलाफ @param sanitizing

 DECLARE @insert NVARCHAR(MAX) 
SELECT @insert = 'INSERT INTO [dbo].[' + @table + '] VALUES... 
EXEC (@insert) 

यह INSERT में स्तंभ मान भी शामिल है:

 DECLARE @insert NVARCHAR(MAX) 
SELECT @insert = 
    'INSERT INTO [dbo].[' + @table + '] VALUES (N''' + @message + ''')' 
EXEC (@insert) 

अब, मैं इंजेक्शन हमले के बारे में स्पष्ट रूप से चिंतित हूं, और यह सुनिश्चित करना चाहता हूं कि @ संदेश का मान @ insert का मान दुर्भावनापूर्ण या EXEC को क्वेरी के रूप में विकृत नहीं कर सकता है।

यह हमें मेरे प्रश्न पर लाता है: @ message में वर्णों से बच रहा है? क्या कोई अन्य पात्र है जो @ message में दिखाई दे सकता है जो बाहर निकल सकता है?

उदाहरण:

 DECLARE @insert NVARCHAR(MAX) 
SELECT @message = REPLACE(@message,'''','''''') 
SELECT @insert = 
    'INSERT INTO [dbo].[' + @table + '] VALUES (N''' + @message + ''')' 
EXEC (@insert) 

(जब मैं कहता हूं " है", ऐसा इसलिए है क्योंकि मेरी क्वेरी संग्रहीत प्रक्रिया में है, और यह संग्रहीत प्रक्रिया @table स्वीकार करती है, जो INSERT की गंतव्य तालिका है में। मुझे अपने आर्किटेक्चर पर चर्चा करने में दिलचस्पी नहीं है या क्यों एक प्रक्रिया पैरामीटर के माध्यम से INSERT में तालिका "गतिशील रूप से" निर्दिष्ट है। कृपया इस पर टिप्पणी करने से बचें जब तक कि तालिका निर्दिष्ट करने के लिए EXEC() क्वेरी के अलावा कोई अन्य तरीका न हो जब इनपुट नाम पैरामीटर के रूप में प्राप्त किया जाता है तो INSERT में)।

+1

क्या हम वास्तव में उन प्रश्नों से निपटना चाहते हैं जो जानबूझकर खराब कोड लिखने के तरीके से निपटते हैं? – dkretz

+7

यदि इसका मतलब है समाधान ढूंढना, हाँ। डेवलपर्स को हर समय बकवास कोड से निपटना पड़ता है, खासकर यदि आप $ 8/घंटा के लिए बांग्लादेश में लिखी गई परियोजनाओं से परामर्श और उत्तराधिकारी हैं। हम हमेशा परियोजनाओं को खरोंच से लक्जरी नहीं पाते हैं, जिससे उन्हें * जिस तरह से किया जाना चाहिए था।:) – core

उत्तर

10

sp_executesql और अंतर्निहित quotename() का उपयोग करें। यह आलेख, The Curse and Blessings of Dynamic SQL, काफी निश्चित संदर्भ है।

+0

++ कैनोलिक संदर्भ – dkretz

+0

जाहिर है कि 2008 में भी, नामांकन() में 128-लंबाई सीमा है, क्योंकि यह एक एसक्यूएल पहचानकर्ता की अपेक्षा करता है। संदर्भ एक उद्धरण() फ़ंक्शन (http://www.sommarskog.se/dynamic_sql.html#quotestring) बनाने का सुझाव देता है, जो वास्तव में वही चीज़ करता है जैसे REPLACE (@variable, '' '', '' '' '' ')। – core

1

EXEC (@somesql) को कॉल करने के बजाय, मैं sp_executesql stored procedure का उपयोग करने का सुझाव देता हूं। विशेष रूप से, यह आपको पैरामीटर पास करने की अनुमति देता है, और सिस्टम जांच करेगा कि पैरामीटर वैध हैं।

+0

हाँ, दुर्भाग्य से, SQL सर्वर 2008 एक्सप्रेस मुझे बता रहा है "तालिका चर 'घोषित करना चाहिए' @my_table '।" उस कोड को निष्पादित करने के बाद। – core

+0

मुझे यकीन था कि मैंने SQL सर्वर 2005 में ऐसा किया है, लेकिन मैं मानता हूं कि मैं बहुत थक गया था। मैं क्षमाप्रार्थी हूं। मैं कल यह कोशिश करूंगा। –

+0

नहीं, मैं गलत हूँ। मैं जवाब के उस खंड को हटा दूंगा। –

1

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

DECLARE @Table AS VARCHAR(MAX) 
DECLARE @Exists AS BIT 

SET @Table = 'Vicious malformed dynamic SQL' 

SELECT @Exists = COUNT(TABLE_NAME) 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME = @Table 

IF (@Exists = 1) 
    BEGIN 
    PRINT 'Table exists' 
    -- Execute dynamic SQL. 
    END 
ELSE 
    PRINT 'Invalid table' 

, अपने परीक्षण के अनुसार, (या बस का उपयोग करते हैं मौजूद है (का चयन करें ....)) 2008 में भी

+0

अच्छी सोच। मैं जो कर रहा हूं वह कर रहा हूं। क्या इसका कोई फायदा है? मैं क्या कर रहा हूं: "अगर OBJECT_ID (@ टेबल, 'यू') नल है ..." – core

0

जाहिर है वहाँ एक 128-लंबाई quotename करने के लिए (सीमा है) के बाद से यह एक एसक्यूएल उम्मीद पहचानकर्ता। मैं प्रस्ताव कर रहा हूँ कि इस सवाल का जवाब से बाहर एक समारोह बनाने के लिए ऊपर REPLACE(), तो तरह है

REPLACE(@variable,'''','''''') 

इसलिए:

CREATE FUNCTION quotestring(@string nvarchar(MAX)) 
RETURNS nvarchar(MAX) AS 
BEGIN 
    RETURN(REPLACE(@string,'''','''''')) 
END 
संदर्भ एक quotestring() समारोह है, जो के रूप में एक ही बात करता है बनाने का सुझाव

... जब तक मैंने कुछ गलत समझा नहीं है।

+0

क्या आप इस तरह के पैरामीटर के रूप में एक nvarchar (MAX) पास कर सकते हैं? –

+0

ज़रूर, क्यों नहीं? यह अब मेरे देव में एक ऑपरेटिंग समारोह है। वातावरण। :) – core

संबंधित मुद्दे