2008-09-19 17 views
8

मेरे पास कुछ कोड है जो इंजेक्शन के खिलाफ रोकने के लिए पैरामीटरयुक्त प्रश्नों का उपयोग करता है, लेकिन मुझे तालिका की संरचना के बावजूद क्वेरी को गतिशील रूप से बनाने में सक्षम होना चाहिए। ऐसा करने का सही तरीका क्या है?पैरामीटरेटेड एसक्यूएल कॉलम?

यहां एक उदाहरण है, कहें कि मेरे पास कॉलम नाम, पता, टेलीफोन के साथ एक टेबल है। मेरे पास एक वेब पेज है जहां मैं चलाता हूं कॉलम दिखाएं और विकल्पों के साथ उनके साथ एक ड्रॉप-डाउन को पॉप्युलेट करें।

अगला, मेरे पास खोज नामक एक टेक्स्टबॉक्स है। यह टेक्स्टबॉक्स पैरामीटर के रूप में प्रयोग किया जाता है।

वर्तमान में मेरे कोड इस तरह दिखता है:

 
result = pquery('SELECT * FROM contacts WHERE `' + escape(column) + '`=?', search); 

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

मैं कैसे सुनिश्चित कर सकता हूं कि यह मेरा इरादा है?

संपादित करें: कारण मैं गतिशील प्रश्नों की आवश्यकता है कि स्कीमा उपयोगकर्ता के विन्यास योग्य है है, और मैं चारों ओर कुछ भी हार्ड-कोडेड ठीक करने के लिए नहीं किया जाएगा।

उत्तर

6

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

@columns = qw/Name Address Telephone/; 
if ($columns[$param]) { 
    $query = "select * from contacts where $columns[$param] = ?"; 
} else { 
    die "Invalid column!"; 
} 

run_sql($query, $search); 
+0

हार्ड कोडिंग मेरे लिए एक विकल्प नहीं है, सुझाव के लिए धन्यवाद! – Martin

+0

मेरा बिंदु स्तंभ नामों को हार्डकोड नहीं करना है, लेकिन उन्हें इंटरफ़ेस से पास नहीं करना है। आप गतिशील रूप से कॉलम की सूची प्राप्त कर सकते हैं, और अभी भी ऊपर दिए गए एक ही समाधान का उपयोग कर सकते हैं। बस पास किए गए डेटा का कॉलम नाम भाग न बनाएं - जो आपको किसी भी SQL इंजेक्शन से सुरक्षित रखेगा। – zigdon

+0

+1 हां, मुझे यह कहना पसंद है: उपयोगकर्ताओं को डेटा दर्ज करने दें, लेकिन उपयोगकर्ताओं को कोड प्रदान करने दें। –

0

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

फिर भी, यह किया जा सकता है, मैं कॉलम नाम को सत्यापित करने के लिए एक अलग — और सख्त — फ़ंक्शन की अनुशंसा करता हूं। यह केवल एक ही पहचानकर्ता को स्वीकार करने की अनुमति दें, जैसे

 
/^\w[\w\d_]*$/ 

कुछ आप मान्यताओं आप अपने खुद के स्तंभ नाम के बारे में कर सकते हैं पर भरोसा करना होगा।

0

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

भाग्य का सबसे अच्छा

0

के परिणामों के आधार स्तंभ बनाओ एक तालिका के लिए एक और क्वेरी जो संभावित स्कीमा मानों को दर्शाती है। उस दूसरी क्वेरी में आप कॉलम नाम के चयन को हार्डकोड कर सकते हैं जिसका उपयोग स्कीमा को परिभाषित करने के लिए किया जाता है। यदि कोई पंक्तियां वापस नहीं आती हैं तो दर्ज कॉलम अमान्य है।

0

मानक एसक्यूएल में, आप डबल कोट्स में सीमित पहचानकर्ता संलग्न करते हैं।इसका मतलब है कि:

SELECT * FROM "SomeTable" WHERE "SomeColumn" = ? 

एक मेज से पता चला पूंजीकरण (नहीं नाम के एक मामले परिवर्तित संस्करण) के साथ SomeTable कहा जाता है से चयन होगा, और पता चला पूंजीकरण के साथ एक स्तंभ कहा जाता SomeColumn करने के लिए एक शर्त लागू होगी।

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

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

विभिन्न डीबीएमएस के पास सीमित पहचानकर्ता प्रदान करने के विभिन्न तरीके हैं। उदाहरण के लिए, एमएस एसक्यूएल सर्वर डबल कोट्स के बजाय स्क्वायर ब्रैकेट [कुछटेबल] का उपयोग करता प्रतीत होता है।

0

कुछ डेटाबेस में कॉलम नामों में रिक्त स्थान हो सकते हैं, जिसका अर्थ है कि आपको कॉलम नाम उद्धृत करना होगा, लेकिन यदि आपके डेटाबेस में ऐसे कोई कॉलम नहीं हैं, तो बस नियमित अभिव्यक्ति या स्प्लिसिंग से पहले किसी प्रकार की जांच के माध्यम से कॉलम नाम चलाएं एसक्यूएल में:

if ($column !~ /^\w+$/) { 
    die "Bad column name [$column]"; 
} 
संबंधित मुद्दे