संग्रहीत प्रक्रियाएँ जादुई रूप से SQL इंजेक्शन को रोकती नहीं हैं, लेकिन वे इसे रोकना बहुत आसान है। आपको बस इतना करना है कि निम्नलिखित कुछ है (उदाहरण उदाहरण के लिए):
CREATE OR REPLACE FUNCTION my_func (
IN in_user_id INT
)
[snip]
SELECT user_id, name, address FROM my_table WHERE user_id = in_user_id; --BAM! SQL INJECTION IMMUNE!!
[snip]
बस! समस्या केवल तब होती है जब स्ट्रिंग संघनन (यानी गतिशील एसक्यूएल) के माध्यम से एक क्वेरी बनाते हैं, और यहां तक कि उन मामलों में भी आप बांधने में सक्षम हो सकते हैं! (डेटाबेस पर निर्भर करता है।)
अपनी गतिशील क्वेरी में SQL इंजेक्शन से कैसे बचें:
चरण 1) अपने आप से पूछें कि क्या आपको वास्तव में एक गतिशील क्वेरी की आवश्यकता है। यदि आप केवल इनपुट सेट करने के लिए तार एक साथ चिपका रहे हैं, तो आप शायद इसे गलत कर रहे हैं। (इस नियम के अपवाद हैं - एक अपवाद कुछ डेटाबेस पर प्रश्नों की रिपोर्टिंग के लिए है, आपके पास निष्पादन के मुद्दे हो सकते हैं यदि आप इसे प्रत्येक निष्पादन के साथ एक नई क्वेरी को संकलित करने के लिए मजबूर नहीं करते हैं। लेकिन इससे पहले कि आप उसमें कूदें, इस मुद्दे पर शोध करें। )
चरण 2) अपने विशेष RDBMS के लिए चर सेट करने के लिए उचित तरीके पर शोध करें। उदाहरण के लिए Oracle आपको निम्नलिखित करने देता है (उनके डॉक्स से उद्धृत):
sql_stmt := 'UPDATE employees SET salary = salary + :1 WHERE '
|| v_column || ' = :2';
EXECUTE IMMEDIATE sql_stmt USING amount, column_value; --INJECTION IMMUNE!!
यहां आप अभी भी इनपुट नहीं कर रहे हैं। आप सुरक्षित रूप से बाध्यकारी हैं! हुर्रे!
यदि आपका डेटाबेस ऊपर की तरह कुछ का समर्थन नहीं करता है (उम्मीद है कि उनमें से कोई भी अभी भी यह खराब नहीं है, लेकिन मुझे आश्चर्य नहीं होगा) - या यदि आपको अभी भी अपने इनपुट को संक्षिप्त करना होगा (जैसे कि कभी-कभी रिपोर्टिंग प्रश्नों के "केस" के रूप में मैंने ऊपर संकेत दिया), तो आपको एक उचित भागने के कार्य का उपयोग करना चाहिए। इसे स्वयं न लिखें। उदाहरण के लिए postgres उद्धरण_literal () फ़ंक्शन प्रदान करता है। तो आप दौड़ेंगे:
sql_stmt := 'SELECT salary FROM employees WHERE name = ' || quote_literal(in_name);
इस तरह अगर in_name '[स्निप] या 1 = 1' ("या" 1 = 1 "भाग की तरह कुछ कुटिल है, तो सभी पंक्तियों का चयन करें, जिससे उपयोगकर्ता को वह वेतन नहीं देखना चाहिए!), तो बोली_लिटरल आपके बट को बचाता है! परिणामी स्ट्रिंग बनाना:
SELECT salary FROM employees WHERE name = '[snip] or 1=1'
कोई परिणाम नहीं मिलेगा (जब तक कि आपके पास वास्तव में अजीब नामों वाले कुछ कर्मचारी न हों।)
यही इसका सार है! अब मैं आपको केवल घर पर ड्राइव करने के लिए SQL इंजेक्शन के विषय पर Oracle गुरु टॉम कय्टे द्वारा एक क्लासिक पोस्ट के लिंक के साथ छोड़ देता हूं: Linky