जब डेटाबेस प्रश्नों की बात आती है, तो हमेशा तैयार किए गए प्रश्नों का उपयोग करें। mysqli
और PDO
पुस्तकालयों इस समर्थन करते हैं। यह इस तरह के भागने के कार्यों का उपयोग करने से अधिक सुरक्षित है mysql_real_escape_string
।
हाँ, mysql_real_escape_string
प्रभावी रूप से सिर्फ एक स्ट्रिंग भागने का कार्य है। यह कोई जादू की गोली नहीं है। यह सब करना खतरनाक पात्रों से बच जाएगा ताकि वे एक ही क्वेरी स्ट्रिंग में उपयोग करने के लिए सुरक्षित हो सकें। हालांकि, यदि आप पहले से अपने इनपुट्स को सैनिटाइज नहीं करते हैं, तो आप कुछ अटैक वैक्टर के लिए कमजोर होंगे।
निम्नलिखित एसक्यूएल की कल्पना करें:
$result = "SELECT fields FROM table WHERE id = ".mysql_real_escape_string($_POST['id']);
आपको यह देखने में सक्षम होना चाहिए कि यह शोषण की चपेट में है।
कल्पना कीजिए कि id
पैरामीटर में आम अटैक वेक्टर है:
1 OR 1=1
सांकेतिक शब्दों में बदलना करने के लिए कोई जोखिम भरा चार्ट नहीं है, इसलिए यह सीधे भागने वाले फिल्टर से होकर गुजरेगा। हमें छोड़कर:
SELECT fields FROM table WHERE id= 1 OR 1=1
जो एक प्यारा SQL इंजेक्शन वेक्टर है और हमलावर को सभी पंक्तियों को वापस करने की अनुमति देगा। या
1 or is_admin=1 order by id limit 1
जो पैदा करता है
SELECT fields FROM table WHERE id=1 or is_admin=1 order by id limit 1
जो हमलावर को इस पूरी तरह से काल्पनिक उदाहरण में पहले प्रशासक के विवरण को वापस करने की अनुमति देता है।
जब भी ये कार्य उपयोगी होते हैं, इनका उपयोग सावधानी से किया जाना चाहिए। आपको यह सुनिश्चित करने की आवश्यकता है कि सभी वेब इनपुट कुछ हद तक मान्य हैं। इस मामले में, हम देखते हैं कि हमारा शोषण किया जा सकता है क्योंकि हमने जाँच नहीं की कि एक चर हम एक संख्या के रूप में उपयोग कर रहे थे, वास्तव में संख्यात्मक था। PHP में आपको व्यापक रूप से फ़ंक्शन के एक सेट का उपयोग करना चाहिए ताकि यह जांचा जा सके कि इनपुट पूर्णांक, फ़्लोट, अल्फ़ान्यूमेरिक आदि हैं, लेकिन जब यह एसक्यूएल की बात आती है, तो तैयार किए गए स्टेटमेंट के अधिकांश मूल्य को ध्यान में रखा जाता है। उपरोक्त कोड सुरक्षित होता अगर यह एक तैयार स्टेटमेंट होता क्योंकि डेटाबेस फ़ंक्शन यह जानते होंगे कि 1 OR 1=1
यह एक मान्य शाब्दिक नहीं है।
के लिए के रूप में htmlspecialchars()
। वह अपनी खुद की एक खान है।
PHP में एक वास्तविक समस्या यह है कि इसमें अलग-अलग HTML से संबंधित भागने वाले कार्यों का एक पूरा चयन है, और वास्तव में कोई स्पष्ट मार्गदर्शन नहीं है कि क्या कार्य करता है।
सबसे पहले, यदि आप एक HTML टैग के अंदर हैं, तो आप वास्तविक परेशानी में हैं। की ओर देखें
echo '<img src= "' . htmlspecialchars($_GET['imagesrc']) . '" />';
हम पहले से ही एक HTML टैग के अंदर हैं, इसलिए हमें कुछ भी खतरनाक करने के लिए <या> की आवश्यकता नहीं है। हमारा हमला वेक्टर सिर्फ हो सकता हैjavascript:alert(document.cookie)
अब परिणामी HTML जैसा दिखता है
<img src= "javascript:alert(document.cookie)" />
हमले के माध्यम से सीधे हो जाता है।
ये और ख़राब हो जाता है। क्यों? क्योंकि htmlspecialchars
(जब इस तरह कहा जाता है) केवल दोहरे उद्धरण चिह्नों और एकल नहीं को कूटबद्ध करता है। तो अगर हमारे पास था
echo "<img src= '" . htmlspecialchars($_GET['imagesrc']) . ". />";
हमारा दुष्ट हमलावर अब पूरे नए मापदंडों को इंजेक्ट कर सकता है
pic.png' onclick='location.href=xxx' onmouseover='...
हमें देता है
<img src='pic.png' onclick='location.href=xxx' onmouseover='...' />
इन मामलों में, कोई जादू की गोली नहीं है, आपको बस इनपुट को खुद को तैयार करना होगा। यदि आप कोशिश करते हैं और बुरे पात्रों को छानते हैं तो आप निश्चित रूप से असफल होंगे। एक श्वेतसूची दृष्टिकोण लें और केवल उन वर्णों के माध्यम से जाने दें जो अच्छे हैं। को देखो XSS नकल पुस्तिकाओं कैसे विविध वैक्टर हो सकता है पर उदाहरण के लिए
यहां तक कि अगर आप htmlspecialchars($string)
HTML टैग के बाहर का उपयोग करते हैं, तो भी आप मल्टी-बाइट चारसेट अटैक वैक्टर की चपेट में हैं।
सबसे प्रभावी आप mb_convert_encoding और htmlentities के संयोजन का उपयोग इस प्रकार कर सकते हैं।
$str = mb_convert_encoding($str, 'UTF-8', 'UTF-8');
$str = htmlentities($str, ENT_QUOTES, 'UTF-8');
यहां तक कि यह IE6 को कमजोर बनाता है, क्योंकि यह जिस तरह से UTF को संभालता है। हालाँकि, आप IE6 उपयोग बंद होने तक ISO-8859-1 जैसे अधिक सीमित एन्कोडिंग पर वापस गिर सकते हैं।
मल्टीबीट समस्याओं के लिए अधिक गहराई से अध्ययन के लिए, https://stackoverflow.com/a/12118602/1820 देखें