स्ट्रिंग के रूप में सुरक्षित एसक्यूएल कथन बनाना

मैं सी # और .NET 3.5 का उपयोग कर रहा हूँ। मुझे कुछ टी-एसक्यूएल सम्मिलन कथन उत्पन्न करने और स्टोर करने की आवश्यकता है जिसे बाद में रिमोट सर्वर पर निष्पादित किया जाएगा।

उदाहरण के लिए, मेरे पास कर्मचारियों की एक सरणी है:

new Employee[]
{
   new Employee { ID = 5, Name = "Frank Grimes" },
   new Employee { ID = 6, Name = "Tim O'Reilly" }
}

और मुझे तारों की एक सरणी के साथ समाप्त करने की जरूरत है, इस तरह:

"INSERT INTO Employees (id, name) VALUES (5, 'Frank Grimes')",
"INSERT INTO Employees (id, name) VALUES (6, 'Tim O''Reilly')"

मैं कुछ कोड देख रहा हूं जो स्ट्रिंग.फॉर्मैट के साथ सम्मिलित बयान तैयार करता है, लेकिन यह सही नहीं लगता है। मैंने SqlCommand का उपयोग करने पर विचार किया ( कुछ ऐसा करने की उम्मीद है यह ), लेकिन यह पैरामीटर के साथ कमांड पाठ को गठबंधन करने का कोई तरीका नहीं प्रदान करता है।

क्या यह सिंगल कोट्स को प्रतिस्थापित करने और स्ट्रिंग बनाने के लिए पर्याप्त है?

string.Format("INSERT INTO Employees (id, name) VALUES ({0}, '{1}')",
    employee.ID,
    replaceQuotes(employee.Name)
    );

ऐसा करने के बारे में मुझे क्या चिंतित होना चाहिए? स्रोत डेटा काफी सुरक्षित है, लेकिन मैं बहुत अधिक धारणाएं नहीं बनाना चाहता हूं।

संपादित करें: बस यह इंगित करना चाहते हैं कि इस मामले में, मेरे पास SQL ​​सर्वर से सीधे कनेक्ट करने के लिए कोई SQL कनेक्शन या कोई तरीका नहीं है। इस विशेष ऐप को एसक्यूएल कथन उत्पन्न करने की आवश्यकता है और उन्हें कहीं और निष्पादित करने के लिए कतारबद्ध करने की आवश्यकता है - अन्यथा मैं SqlCommand.Parameters का उपयोग कर रहा हूं। AddWithValue ()

0
AddWithValue बहुत अच्छा है (मैं इसे अक्सर उपयोग करता हूं), लेकिन अगर गलत तरीके से उपयोग नहीं किया जाता है तो यह गलत अंतर्निहित प्रकार रूपांतरण से पीड़ित हो सकता है।
जोड़ा लेखक Mitch Wheat, स्रोत

5 उत्तर

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

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

0
जोड़ा

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

0
जोड़ा

पैरामीटरयुक्त कमांड का प्रयोग करें। पैरामीटर को अपने रिमोट सर्वर के साथ पास करें, और उसे SQL सर्वर में कॉल करने के लिए प्राप्त करें, फिर भी SQL स्वयं और पैरामीटर मानों के बीच भेद बनाए रखें।

जब तक आप इलाज डेटा को कोड के रूप में कभी नहीं मिलाते, तब तक आपको ठीक होना चाहिए।

0
जोड़ा
उपदेश? क्या रिकॉर्डिंग हैं?
जोड़ा लेखक tofutim, स्रोत
यह एक समाधान प्रदान नहीं करता है जब यह एक कठिन आवश्यकता है कि उत्पादन एक .sql स्क्रिप्ट फ़ाइल है जिसे तैयार किए गए INSERT कमांड के साथ डेटा डालने के साथ किया गया है।
जोड़ा लेखक O. R. Mapper, स्रोत
@ जोन्स स्केट: सच - ओपी के लिए शायद ठीक है, फिर भी भविष्य में आने वाले लोगों के लिए कुछ हद तक परेशान है जो वास्तव में प्रश्न में वर्णित समस्या का सामना करते हैं।
जोड़ा लेखक O. R. Mapper, स्रोत
वास्तव में, बस बिस्तर पर जा रहा है। कल सुबह 10.30-11.30 तक पहुंचे, इसलिए आपको चाबुक पर एक अच्छी दरार की गारंटी है! ;)
जोड़ा लेखक Jon Skeet, स्रोत
@tofutim: ऐसा नहीं है कि मुझे पता है।
जोड़ा लेखक Jon Skeet, स्रोत
@ ओआर.मैपर: दरअसल - ध्यान दें कि ओपी ने उत्तर देने के बाद उस आवश्यकता को जोड़ा, हालांकि उन्होंने अभी भी मेरा जवाब स्वीकार कर लिया है, विचित्र रूप से पर्याप्त ...
जोड़ा लेखक Jon Skeet, स्रोत

अपने प्रतिस्थापन कोट्स को इस तरह से ठीक करें:

void string replaceQuotes(string value) {
     string tmp = value;
     tmp = tmp.Replace("'", "''");
     return tmp;
}

चीयर्स!

0
जोड़ा
@ KarelFrajták: पैरामीटर का उपयोग तब किया जा सकता है जब स्वरूपित आदेश केवल बाद में निष्पादित किए जा रहे हैं (संभवतः, सी # कोड के निष्पादन के बाद), जैसा कि प्रश्न में वर्णित है?
जोड़ा लेखक O. R. Mapper, स्रोत
पैरामीटर का उपयोग करना बहुत आसान है, उन सभी पात्रों के बारे में सोचें जिन्हें बच जाना चाहिए। और यह एसक्यूएल इंजेक्शन सुरक्षित नहीं है।
जोड़ा लेखक Karel Frajták, स्रोत
@ ओ.आर.मैपर, उस मामले में, मैं पैरामीटर नाम और मूल्यों के साथ बयान और एक शब्दकोश कतारबद्ध करता हूं।
जोड़ा लेखक Karel Frajták, स्रोत

अपनी SqlCommand ऑब्जेक्ट को इस प्रकार बनाएं:

SqlCommand cmd = new SqlCommand(
        "INSERT INTO Employees (id, name) VALUES (@id, @name)", conn);

SqlParameter param  = new SqlParameter();
param.ParameterName = "@id";
param.Value         = employee.ID;

cmd.Parameters.Add(param);

param  = new SqlParameter();
param.ParameterName = "@name";
param.Value         = employee.Name;

cmd.Parameters.Add(param);

cmd.ExecuteNonQuery();
0
जोड़ा
मुझे वह सब मिलता है और यह भी मेरे जवाब पर मिलता है।
जोड़ा लेखक Cade Roux, स्रोत
यह सवाल का जवाब कैसे देता है? ओपी स्पष्ट रूप से बताता है कि उनके पास डीबी तक पहुंच नहीं है और इसके बजाय बाद में आदेशों को आउटपुट करने की आवश्यकता है जिन्हें बाद में चलाया जा सकता है।
जोड़ा लेखक O. R. Mapper, स्रोत
ब्रैड विल्सन: एक अतिरिक्त "पैरामीटर" की आवश्यकता है: cmd.Parameters.AddWithValue ("@ id", staff.ID);
जोड़ा लेखक Csaba Toth, स्रोत
"Cmd.AddWithValue (" @ id ", कर्मचारी.आईडी) का उपयोग करना;" बहुत ज्यादा है।
जोड़ा लेखक Brad Wilson, स्रोत