DB से कनेक्ट किए बिना mysql_real_escape_string के लिए वैकल्पिक


91

मैं कई बार डेटाबेस से कनेक्ट किए बिना mysql_real_escape_string के रूप में व्यवहार करने वाला एक कार्य करना चाहता हूं क्योंकि मुझे DB कनेक्शन के बिना सूखा परीक्षण करने की आवश्यकता है। mysql_escape_string पदावनत है और इसलिए अवांछनीय है। मेरे कुछ निष्कर्ष:

http://www.gamedev.net/community/forums/topic.asp?topic_id=448909

http://w3schools.invisionzone.com/index.php?showtopic=20064



1
+1 मैं खुद MySQL क्लास लिख रहा हूं और पैरामीटर बाइंडिंग उद्देश्य के लिए mysql_real_escape_string () का उपयोग कर रहा हूं। मैं mysqli का उपयोग करने से बचता हूं क्योंकि सभी होस्टिंग इसका समर्थन नहीं करते हैं। मैं मल्टी-फाइल और मल्टी-क्लास लाइब्रेरी से भी बचता हूं। मुझे जो चाहिए वो सिर्फ एक साफ सुथरा सिंगल क्लास है। धन्यवाद!
वियतनामी

मेरे लिए भी +1। मेरा उपयोग-मामला एक SugarCRM APi है जहाँ मुझे API के माध्यम से SQL के अंशों को सुदूर SugarCRM उदाहरण में धकेलने की आवश्यकता है। बुरा हालांकि यह है कि, यह वही है जिसके साथ मुझे काम करना है (कुछ सुगरक्रिम देव प्रमुखों के साथ मिलकर दस्तक दें)। मुझे API का उपयोग करने वाले एप्लिकेशन में SQL में स्ट्रिंग्स से बचने की आवश्यकता है और यह SugarCRM उदाहरण के पीछे डेटाबेस से पूरी तरह से अलग है।
जेसन

जवाबों:


75

DB कनेक्शन के बिना स्ट्रिंग को सुरक्षित रूप से बचाना असंभव है। mysql_real_escape_string()और तैयार किए गए कथनों को डेटाबेस के लिए एक कनेक्शन की आवश्यकता होती है ताकि वे उपयुक्त वर्ण सेट का उपयोग करके स्ट्रिंग से बच सकें - अन्यथा SQL इंजेक्शन हमले बहु-बाइट वर्णों का उपयोग करके अभी भी संभव हैं।

यदि आप केवल परीक्षण कर रहे हैं , तो आप भी उपयोग कर सकते हैं mysql_escape_string(), यह SQL इंजेक्शन हमलों के खिलाफ 100% गारंटी नहीं है, लेकिन DB कनेक्शन के बिना कुछ भी सुरक्षित बनाना असंभव है।


1
नोट के लिए +1 धन्यवाद। मुझे यकीन नहीं है कि बहु-बाइट वर्णों का उपयोग करके SQL इंजेक्शन हमलों के खिलाफ कैसे परीक्षण किया जाए।
वियत

2
अपडेट करने के लिए मुझे कुछ पुराने कोड दिए गए हैं। यह mysql_escape_stringएक कनेक्शन के बिना उपयोग करता है (फिर भी यह पता लगाने की कोशिश क्यों की जाती है)। चूँकि उस फ़ंक्शन को हटा दिया गया है, मैं सोच रहा हूँ कि मैं इसे कैसे बदल सकता हूँ। यह निश्चित रूप से उचित लगता है कि कोई भी कनेक्शन को खोले बिना "फ़ंक्शन में" उपयुक्त वर्ण सेट को निर्दिष्ट कर सकता है।
जॉनके

3
असंभव? Mysql_real_escape_string को डेटाबेस कनेक्शन से क्या मिलता है जो कॉन्फ़िगरेशन डेटा नहीं है जो हाथ से एक समान फ़ंक्शन में पारित किया जा सकता है? संपादित करें: बस नीचे पढ़ा गया है, यह MySQL के भीतर एक पुस्तकालय फ़ंक्शन को कॉल करता है, इसलिए कुछ प्रसंस्करण है जो PHP के बाहर होता है। यह अभी भी पोर्टेबल हो सकता है, लेकिन इसे अद्यतित रखना अपने आप में एक परियोजना होगी।
जेसन

2
क्या होगा अगर DB चरित्र सेट समय से पहले जाना जाता है?
jchook

7
यदि आप चरित्र सेट जानते हैं, तो क्या बिना कनेक्शन के भागने से रोकता है?
जोहान

66

खैर, mysql_real_escape_string फ़ंक्शन संदर्भ पृष्ठ के अनुसार : "mysql_real_escape_string () MySQL के लाइब्रेरी फ़ंक्शन को mysql_real_escape_string कहते हैं, जो निम्न वर्णों से बच जाता है: \ x00, \ r, \,,", "और \" Xa। "

इसे ध्यान में रखते हुए, फिर आपके द्वारा पोस्ट किए गए दूसरे लिंक में दिए गए फ़ंक्शन को वही करना चाहिए जो आपको चाहिए:

function mres($value)
{
    $search = array("\\",  "\x00", "\n",  "\r",  "'",  '"', "\x1a");
    $replace = array("\\\\","\\0","\\n", "\\r", "\'", '\"', "\\Z");

    return str_replace($search, $replace, $value);
}

6
धन्यवाद। मैं कुछ और सुझाता हूं: फ़ंक्शन एस्केप ($ aQuery) {रिटर्न स्ट्रेट ($ aQuery, सरणी ("\ x00" => '\ x00', "\ n" => '\ n', "\ r" => '\ r', '\\' => '\\\\', "'" => "\", "" = "> \", "\" ; }
वियतनाम

1
क्यों \ X1a को \\ X1a के बजाय \\\ X1a के साथ बदल दिया जाता है? क्या यह एक टाइपो है?
माइकल ज़ेड

16
-1 यह बेहद खतरनाक है। यदि डेटाबेस कनेक्शन एक मल्टीबाइट कैरेक्टर सेट का उपयोग कर रहा है, तो इस तरह की सरल बायटेविज़ रिप्लेसमेंट डेटा करप्शन (भागने वाले / वर्णों को शामिल करते हुए) को जन्म दे सकती है - यह मनमाने ढंग से एसक्यूएल को इंजेक्ट करने के लिए दुर्भावनापूर्ण हमलावर द्वारा शोषण किया जा सकता है।
अर्ग्यल

यदि आप इस पर चरित्र सेट को गलत पाते हैं तो यह खतरनाक हो सकता है। मल्टीबाइट कैरेक्टर सेट के लिए, अगर mysql उपयोग कर रहा है कि कोई व्यक्ति केवल \\ को रद्द करने के लिए एक बाइट में डाल सकता है। मल्टीबीट कैरेक्टर्स अक्सर कुछ भी ले सकते हैं क्योंकि mysql के लिए \\ सहित दूसरा बाइट इसे एक स्टैंडअलोन \\ के रूप में देखता है लेकिन मल्टीबाइट चरित्र का हिस्सा है। मुझे नहीं पता कि UTF8 के साथ क्या होता है। मुझे उम्मीद है कि [0xB0, '\\' के साथ एक अमान्य बाइट \\ को मारने पर जो बस रुक जाती है और इसे फिर से निगलने के बजाय उस बाइट के साथ शुरू होती है।
jgmjgm

1
अगर मुझे पता है कि charset utf8 है, तो क्या ऐसा करने के लिए उपयोग करना सुरक्षित है mb_strpos()(और इसके mb_substr()समान व्यवहार बनाने के लिए substr_replace())?
SOFe

28

मेरे अन्य उत्तर के सीधे विरोध में, यह निम्नलिखित कार्य बहु-बाइट वर्णों के साथ भी सुरक्षित है।

// replace any non-ascii character with its hex code.
function escape($value) {
    $return = '';
    for($i = 0; $i < strlen($value); ++$i) {
        $char = $value[$i];
        $ord = ord($char);
        if($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126)
            $return .= $char;
        else
            $return .= '\\x' . dechex($ord);
    }
    return $return;
}

मुझे उम्मीद है कि कोई खुद से अधिक जानकार मुझे बता सकता है कि ऊपर का कोड क्यों काम नहीं करेगा ...


अतिरिक्त प्रयास के लिए +1 धन्यवाद। मैं बहु-बाइट संबंधित SQL इंजेक्शन के बारे में और जानने के लिए आसपास जा रहा हूं।
वियतनाम

मुझे लगता है कि यह $ रिटर्न होना चाहिए। = 'x'। dechex ($ ord); इसके बजाय
Viet

1
एक सामान्य नियम के रूप में, मैं एकल-उद्धृत स्ट्रिंग्स में भी '\\' का उपयोग करना पसंद करता हूं, सिर्फ इसलिए कि यदि आप सावधान नहीं होते हैं तो एकल '\' अगले चरित्र को प्रभावित कर सकता है। मैं शायद फिर से ओसीडी जा रहा हूं।
बहुत अधिक php

1
यह फ़ंक्शन mysql भागने के नियमों का पालन नहीं करता है और इसके परिणामस्वरूप डेटा अखंडता का नुकसान होगा। "MySQL टेबल 9.1," स्पेशल कैरेक्टर एस्केप सीक्वेंस "में दिखाए गए एस्केप सीक्वेंस को पहचानता है। अन्य सभी एस्केप सीक्वेंस के लिए, बैकस्लैश को नजरअंदाज कर दिया जाता है। अर्थात, एस्केप किए गए कैरेक्टर की व्याख्या की जाती है जैसे कि वह बच गया हो। उदाहरण के लिए," \ x "। सिर्फ "x" है। - dev.mysql.com/doc/refman/5.6/en/…
velcrow

2
क्या वास्तव में MySQL स्ट्रिंग शाब्दिक पाठ "xAA" से अधिक कुछ भी मतलब नहीं है? दस्तावेज़ीकरण यह कहता प्रतीत होता है कि \ x का कोई विशेष अर्थ नहीं है, इसलिए \ _ को अनदेखा किया जाएगा। dev.mysql.com/doc/refman/5.0/en/string-literals.html
जेसन

6

आगे के शोध से, मैंने पाया है:

http://dev.mysql.com/doc/refman/5.1/en/news-5-1-11.html

सुरक्षा फिक्स:

बहु-बाइट एन्कोडिंग प्रसंस्करण में एक एसक्यूएल-इंजेक्शन सुरक्षा छेद पाया गया है। बग सर्वर में था, गलत तरीके से स्ट्रिंग को पार्स करने से mysql_real_escape_string () C API फ़ंक्शन के साथ बच गया।

यह जोखिम जोश बर्कस और टॉम लेन द्वारा OSDB कंसोर्टियम के अंतर-परियोजना सुरक्षा सहयोग के हिस्से के रूप में खोजा और रिपोर्ट किया गया था। SQL इंजेक्शन के बारे में अधिक जानकारी के लिए, कृपया निम्न पाठ देखें।

चर्चा। बहु-बाइट एन्कोडिंग प्रसंस्करण में एक SQL इंजेक्शन सुरक्षा छेद पाया गया है। SQL इंजेक्शन सुरक्षा छेद में ऐसी स्थिति शामिल हो सकती है जब उपयोगकर्ता किसी डेटाबेस में डाले जाने के लिए डेटा की आपूर्ति करता है, तो उपयोगकर्ता SQL कथन को उस डेटा में इंजेक्ट कर सकता है जिसे सर्वर निष्पादित करेगा। इस भेद्यता के संबंध में, जब चरित्र सेट-अनजान भागने का उपयोग किया जाता है (उदाहरण के लिए, PHP में, अतिरिक्त), कुछ मल्टी-बाइट कैरेक्टर सेट (उदाहरण के लिए, एसजेआईएस, बीआईजी 5 और जीबीके) में भागने को बायपास करना संभव है। परिणामस्वरूप, SQLL इंजेक्शन हमलों को रोकने के लिए Addlashes () जैसे एक फ़ंक्शन सक्षम नहीं है। सर्वर साइड पर इसे ठीक करना असंभव है। सबसे अच्छा समाधान ऐसे mysql_real_escape_string () फ़ंक्शन द्वारा ऑफ़र किए गए वर्ण सेट-अवेयरिंग एस्केप का उपयोग करने के लिए है।

हालाँकि, एक बग का पता चला कि कैसे MySQL सर्वर mysql_real_escape_string () के आउटपुट को पार्स करता है। परिणामस्वरूप, जब वर्ण सेट-जागरूक फ़ंक्शन mysql_real_escape_string () का उपयोग किया गया था, तब भी SQL इंजेक्शन संभव था। इस बग को ठीक कर दिया गया है।

समाधान। यदि आप MySQL को ऐसे संस्करण में अपग्रेड करने में असमर्थ हैं, जिसमें mysql_real_escape_string () पार्सिंग में बग के लिए फ़िक्सेस शामिल हैं, लेकिन MySQL 5.0.1 या उच्चतर चलाएं, तो आप एक वर्कअराउंड के रूप में NO_BACKSLASH_SCAPES SQL मोड का उपयोग कर सकते हैं। (यह मोड MySQL 5.0.1 में पेश किया गया था।) NO_BACKSLASH_ESCAPES SQL मानक संगतता मोड सक्षम करता है, जहां बैकस्लैश को एक विशेष वर्ण नहीं माना जाता है। इसका परिणाम यह होगा कि प्रश्न विफल होंगे।

वर्तमान कनेक्शन के लिए इस मोड को सेट करने के लिए, निम्न एसक्यूएल विवरण दर्ज करें:

SET sql_mode='NO_BACKSLASH_ESCAPES';

आप सभी ग्राहकों के लिए विश्व स्तर पर भी मोड सेट कर सकते हैं:

SET GLOBAL sql_mode='NO_BACKSLASH_ESCAPES';

सर्वर-कमांड विकल्प -sql-mode = NO_BACKSLASH_ESCAPES का उपयोग करके या सर्वर विकल्प फ़ाइल में sql- मोड = NO_BACKSLASH_ESCAPES सेट करके सर्वर शुरू होने पर यह SQL मोड भी स्वचालित रूप से सक्षम किया जा सकता है (उदाहरण के लिए, my.cnf या my.ini , आपके सिस्टम पर निर्भर करता है)। (बग # 8378, CVE-2006-2753)

बग # 8303 भी देखें।


1
यह बहुत पहले तय हो चुका है।
आपका कॉमन सेंस

2
इसके अलावा सावधान रहें जो NO_BACKSLASH_ESCAPES अन्य कमजोरियों का परिचय देता है
अर्ग्यल

2
: - 5.1.11 में फिक्स्ड लिंक टूट गया था, यहाँ संग्रह है web.archive.org/web/20120501203047/http://dev.mysql.com:80/doc/...
Bastion
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.