2011-01-23 7 views
10

मेरे पास एक ऐसा एप्लिकेशन है जो mysql (mysqli) असली एस्केप स्ट्रिंग के साथ संयोजन में गतिशील mysql क्वेरीज़ का उपयोग करके बहुत लाभान्वित होगा। यदि मैं mysql वास्तविक भागने के माध्यम से उपयोगकर्ता से प्राप्त सभी डेटा चलाता हूं तो यह केवल mysql तैयार कथन का उपयोग करने के समान सुरक्षित होगा?क्या गतिशील mysql प्रश्न एसक्यूएल के साथ तैयार बयान के रूप में सुरक्षित से बच रहे हैं?

उत्तर

4

निश्चित रूप से नहीं।

जबकि शीर्षक में प्रश्न अस्पष्ट है और रूप में व्याख्या की जा सकती है "हर यह हिस्सा ठीक से स्वरूपित है के साथ कर रहे हैं गतिशील mysql प्रश्नों ..." और इस तरह एक सकारात्मक जवाब है, शरीर में सवाल यह है कि नहीं:

अगर मैं mysql असली भागने के माध्यम से उपयोगकर्ता से प्राप्त यह बस के रूप में mysql तैयार बयान का उपयोग कर के रूप में सुरक्षित किया जाएगा सभी डेटा भाग गया?

आप करीब इस सवाल का देखो, तो आप समझ जायेंगे कि यह सिर्फ एक जादू अवतार उद्धरण! इस अपमानित, बहिष्कृत और हटाई गई सुविधा का बहुत ही उद्देश्य बिल्कुल "भागने के माध्यम से सभी उपयोगकर्ता इनपुट चलाएं" है।
हर कोई आजकल जानता है कि जादू उद्धरण खराब हैं। तब सकारात्मक जवाब क्यों?

ठीक है, ऐसा लगता है कि इसे फिर से समझाया जाना चाहिए, क्यों थोक भागना बुरा है।

समस्या के मूल एक काफी मजबूत भ्रम, लगभग हर पीएचपी उपयोगकर्ता द्वारा साझा है:
हर कोई एक अजीब धारणा है कि भागने "खतरनाक वर्ण" (? क्या कर रहे हैं वे) उन्हें "सुरक्षित" बनाने पर कुछ करना है (किस तरह?)। कहने की जरूरत नहीं है कि यह एक पूर्ण बकवास है।

सत्य है:

  • से बचने के लिए नहीं है "स्वच्छ" कुछ भी।
  • भागने से इंजेक्शन के साथ कुछ लेना देना नहीं है।
  • भागने से उपयोगकर्ता इनपुट के साथ कुछ लेना देना नहीं है।

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

$clean = mysql_real_escape_string($_POST['some_dangerous_variable']); 
$query = "SELECT * FROM someTable WHERE somevalue = $clean"; 

की तरह एक कोड:

तैयार बयानों के साथ अंतर की बात हो रही है, वहाँ कम से कम एक मुद्दा (जो पहले से ही sql-injection टैग के तहत कई बार उल्लेख किया है)।
जीवित बचाना सिर्फ एक स्ट्रिंग स्वरूपण सुविधा है, किसी भी माध्यम से इंजेक्शन रोकथाम नहीं।
आंकड़े जाओ।
उन दोनों को अगर

  • आप इसे केवल कुख्यात "उपयोगकर्ता इनपुट" के खिलाफ उपयोग कर रहे हैं इंजेक्शन से आप की गारंटी नहीं है, नहीं एक सख्त नियम के रूप में:

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

  • यदि आपको डेटा नहीं बल्कि पहचानकर्ता या कीवर्ड डालने की आवश्यकता है।

इन परिस्थितियों में सुरक्षा के लिए, मेरा उत्तर समझा देख FULL sql injection protection how-to

लंबी कहानी कम:

: आप अपने आप को सुरक्षित केवल यदि आप 2 आवश्यक सुधार और अपने प्रारंभिक बयान के एक इसमें वृद्धि करने पर विचार कर सकते

अगर मैं सभी डेटा उपयोगकर्ता से प्राप्त mysql असली भागने से होकर गुजरता था और हमेशा उद्धरण में यह जोड़ देना (और, के रूप में ircmaxell उल्लेख किया है, mysqli_set_charset() mysqli_real_esc बनाने के लिए प्रयोग किया जाता है एईपी स्ट्रिंग() वास्तव में यह काम करता है (जीबीके जैसे कुछ अजीब एन्कोडिंग का उपयोग करने के इस दुर्लभ अवसर में)) क्या यह mysql तैयार कथन का उपयोग करने के समान सुरक्षित होगा?

इन नियमों के बाद - हाँ, यह देशी तैयार बयान के रूप में सुरक्षित होगा।

+0

मुझे खेद है; मैं picky या कुछ भी करने की कोशिश नहीं कर रहा हूँ ... "_ दोनों दोनों की गारंटी नहीं है _... –

+0

मैं क्षमा चाहता हूँ, क्या आप व्याकरण या अर्थ पर हैं? यदि पूर्व - कृपया मेरी पोस्ट को संपादित करने में संकोच न करें, तो मैं आभारी हूं। मैं मूल निवासी नहीं हूं और कभी-कभी मेरी गलतियों को नहीं देख सकता हूं। –

17

हां, लेकिन एक योग्य हां।

आपको 100% इनपुट से ठीक से बचने की आवश्यकता है। और आपको चरित्र सेट को सही ढंग से सेट करने की आवश्यकता है (यदि आप सी एपीआई का उपयोग कर रहे हैं, तो आपको SET NAMES के बजाय mysql_set_character_set() पर कॉल करने की आवश्यकता है)। यदि आप एक छोटी सी बात याद करते हैं, तो आप कमजोर हैं। तो यह हाँ है, जब तक आप सबकुछ सही करते हैं ...

और यही कारण है कि बहुत से लोग तैयार प्रश्नों की सिफारिश करेंगे। ऐसा नहीं है क्योंकि वे किसी भी सुरक्षित हैं। लेकिन क्योंकि वे अधिक क्षमा कर रहे हैं ...

+0

प्रतिबिंबित बयानों में 2 राउंड ट्रिप, तैयार और निष्पादित होते हैं। क्या प्रत्येक बार डेटाबेस के लिए एक राउंड ट्रिप के रूप में एक चर गणना पर mysql एस्केप स्ट्रिंग चलाता है? – bshack

+0

@bshack: मुझे ऐसा विश्वास नहीं है। यह खुले कनेक्शन से वर्णमाला का उपयोग करता है, इसलिए इसे गोल-यात्रा की आवश्यकता नहीं है (लेकिन मैं गलत हो सकता हूं, मैंने एपीआई के स्रोत कोड का निरीक्षण नहीं किया है, केवल [दस्तावेज़ीकरण] (http: // dev। mysql.com/doc/refman/5.0/en/mysql-real-escape-string.html)) ... – ircmaxell

+0

क्या चरित्र सेट सेट करने के अलावा आपको कुछ और करना है? – Michael

1

मुझे लगता है कि @ircmaxell इसे सही मिला।

एक अनुवर्ती के रूप में, इस तरह की चीज़ के लिए देखो।
मैं हर समय यह करने के लिए इस्तेमाल किया:

<?php 

//sanitize the dangerous posted variable... 
$clean = mysql_real_escape_string($_POST['some_dangerous_variable']); 

//...and then forget to use it! 
$query = "SELECT * FROM someTable WHERE somevalue = '{$_POST['some_dangerous_variable']}'"; 

?> 

और जब मैं कहता हूँ "यह करने के लिए इस्तेमाल किया", क्या मेरा मतलब है कि मैं अंत में छोड़ दिया और बस तैयार बयानों उपयोग शुरू कर दिया है!

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