2011-01-26 8 views
6

थिंक का उपयोग कर मैं MySQL सर्वर से कई कॉल और के साथ एक पूर्ण काम कर रहे वेबसाइट है वह यह है कि मैंने देखा इस साइट पर कुछ शोध कर रही है कि इस रूप में मेरी querys बनाने:एसक्यूएल इंजेक्शन की रोकथाम केवल php

$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'", 
      mysql_real_escape_string($user), 
      mysql_real_escape_string($password)); 

मैं सुरक्षा समस्या को हल कर सकता हूं, लेकिन, जैसा कि मैंने कहा था, मेरे पास MySQL सर्वर पर कई कॉल हैं, और समस्या को हल करने के लिए सबसे अच्छा तरीका (मेरे मामले में) सीधे क्वेरी में गुजरने वाले वर्रों पर जा रहा है लेकिन एक का उपयोग करके whitout MySQL फ़ंक्शन क्योंकि क्वेरी से बाहर हूं।

mysql_query("SELECT * FROM `post` WHERE id=" . $_GET['edit']); 

क्योंकि मैं अपने सभी कोड में इस का एक बहुत है मैं इस क्वेरी के लिए संशोधन नहीं कर सकते, insted मैं वर पर इंजेक्शन के लिए जाँच करने preefer, $ _GET [ ': मुझे यह स्पष्ट करने दें, मैं इस राशि संपादित करें ']।

मैं पूछताछ के चर पर SQL इंजेक्शन के लिए शुद्ध PHP जांच का उपयोग कैसे कर सकता हूं? पसंद:

$_GET['edit']=freehack($_GET['edit']); 
+1

लोगों की संख्या को ऊपर उठाया और पसंदीदा * यह देखकर, * मुझे विश्वास नहीं है कि इस तरह के इतने गरीब डेवलपर्स हैं! तो, इन सभी लोगों को एक ही समस्या है और * समान प्रकार के समाधान की तलाश है? –

+0

इसके अलावा, आप अपने पासवर्ड से बचने से बेहतर नहीं हैं। यदि आप तुलना के लिए इसका उपयोग करने जा रहे हैं तो पासवर्ड एन्क्रिप्ट करें। – Nick

+3

"मैं इस प्रश्न में संशोधन नहीं कर सकता क्योंकि मेरे पास मेरे सभी कोड में बहुत कुछ है" आलसी खराब दोष के रूप में अनावश्यक है। – Andrew

उत्तर

12

इस तरह से ऐसा न करें। "सुरक्षित" संस्करणों के साथ अपने $_GET पैरामीटर के मान को प्रतिस्थापित करके, आप अपने इनपुट डेटा को दूषित कर रहे हैं, जिसे आपको अन्य स्थानों के लिए आवश्यकता हो सकती है।

डेटाबेस परत पर इसका उपयोग करने की आवश्यकता होने पर केवल डेटा से बचें। यह आपको केवल आपके प्रश्नों को ठीक करने में थोड़ा समय लगेगा, और लंबे समय तक आपको सिरदर्द का एक टन बचाएगा।

किसी भी मामले में, आप जो भी कर रहे हैं वह अभी भी सुरक्षित नहीं है! देखें: PHP: Is mysql_real_escape_string sufficient for cleaning user input?

आपको वास्तव में prepared queries with PDO का उपयोग करना चाहिए। साथ ही, आपको क्वेरी में इसका उपयोग करने से पहले वैधता के लिए अपने उपयोगकर्ता इनपुट की जांच करनी चाहिए।

+0

संक्षेप में: तारों से बचने पर, mysql_real_escape_string() का उपयोग करें। पूर्णांक से बचने पर, अंतराल() का उपयोग करें। – TehShrike

+0

'आपको क्वेरी में इसका उपयोग करने से पहले वैधता के लिए अपने उपयोगकर्ता इनपुट की जांच करनी चाहिए' यह एक महत्वपूर्ण हिस्सा है जिसे लोग कभी-कभी भूल जाते हैं। यदि आप एक पूर्णांक की अपेक्षा करते हैं, तो आप क्वेरी में कुछ भी फिट करने की कोशिश करने के बजाय एक पूर्णांक क्यों नहीं देख रहे हैं? – HoLyVieR

+0

@TehShrike पहचानकर्ताओं से बचने पर, श्वेतसूची –

7

"मैं इस प्रश्न में संशोधन नहीं कर सकता क्योंकि मेरे पास मेरे सभी कोड में बहुत कुछ है" सुरक्षा के बारे में बात करते समय गलत दृष्टिकोण है। आपके पास एक बड़ी डिज़ाइन समस्या है जो आपको सभी प्रकार के सुरक्षा मुद्दों पर खुलती है। यहां तक ​​कि अगर आप फ़िल्टर विधि की तरह कुछ करते हैं जो आप अंत में वर्णन करते हैं, तो आप सुनिश्चित नहीं हो सकते कि आप हर मामले को कवर करेंगे।

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

0

मैं "जादू" फ़ंक्शन के साथ नहीं जाऊंगा और यह चर को साफ़ करने की अपेक्षा करता हूं। यह सभी एज केस को हल नहीं करेगा और यह अभी भी कमजोर होगा।

इसका एक अच्छा उदाहरण आपकी दूसरी क्वेरी है। यह अब भी $_GET['edit'] चर के साथ SQL इंजेक्शन भी के लिए कमजोर है।

आपको जो करना है वह आपको प्राप्त होने वाले सभी डेटा को मान्य करता है और जांचता है कि यह आपके द्वारा अपेक्षित डेटा की तरह है या नहीं।

if (SomeValidator::validateInt($_GET['edit'])) { 
    // OK, we continue // 
} else { 
    // Display error, but don't continue ! // 
} 

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

यदि आप सत्यापन और स्वच्छता प्राप्त करना चाहते हैं तो आप ESAPI for PHP का उपयोग कर सकते हैं।

0

मैं तैयार प्रश्नों का उपयोग करके दोनों समर्थन के रूप में PDO इंटरफ़ेस, या MySQLi इंटीफेस का उपयोग करने की अनुशंसा करता हूं। तैयार प्रश्नों का उपयोग करना प्रभावी ढंग से और लगातार अपने आप को एसक्यूएल इंजेक्शन हमलों की रक्षा करने का एकमात्र तरीका है। यदि आप कभी भी डेटाबेस स्विच करने की आवश्यकता होती है, तो मैं व्यक्तिगत रूप से पीडीओ को mysqli पर अनुशंसा करता हूं क्योंकि यह आपके डेटाबेस में डेटाबेस अज्ञेय इंटरफ़ेस प्रदान करता है। यहां तक ​​कि यदि आपको कभी भी डेटाबेस स्विच करने की आवश्यकता नहीं है, तो आपको एक अलग डेटाबेस का उपयोग करके किसी अन्य प्रोजेक्ट को काम करने की आवश्यकता होने पर केवल 1 इंटरफ़ेस सीखना बेहतर होगा।

0
  1. बचें समान क्वेरी आपके आवेदन भर में विभिन्न स्थानों में बार-बार होने - के रूप में बातें हो जाना आप बनाए रखने के लिए एक से अधिक संस्करण है और वे लगभग हमेशा तालमेल न बिठा पाएं। तैयार प्रश्न मेरे लिए अच्छा लगता है (मैं वास्तव में एक PHP लड़का नहीं हूं), या यदि आपको एक और तरीका जाना है तो एक केंद्रीय संदर्भ पुस्तकालय स्थापित करें और वहां अपने प्रश्नों को संग्रहित करें, फिर उन्हें अपने ऐप में उनकी आवश्यकता होने पर संदर्भित करें।

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

  3. यदि आपको करना है .... SQL इंजेक्शन महत्वपूर्ण रूप से एक प्रकार की सुरक्षा समस्या है। यदि आप जानते हैं कि आप एक पूर्णांक पैरामीटर की अपेक्षा कर रहे हैं, "1; ड्रॉप टेबल उपयोगकर्ता; -" वैध इनपुट नहीं है, भले ही इसमें कोई खतरा वर्ण या भागने वाले अनुक्रम न हों। स्ट्रिंग्स या जो भी हो, से बाहर निकलने की जांच न करें, सुनिश्चित करें कि जब आप एक विशिष्ट प्रकार चाहते हैं, तो आपको वह मिलता है और अन्य इनपुट एक त्रुटि फेंकता है।

1

मुझे लगता है कि आप PDO के अंदर अपनी क्वेरी को लपेट सकते हैं।

$unsafe = "SELECT * FROM `post` WHERE id=" . $_GET['edit']; 
$DBH->quote($unsafe); // makes query safe. 

जहां $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);

तो फिर तुम replacements.Then करने के लिए स्क्रिप्ट के कुछ प्रकार लिखने की फिर से मैं वास्तव में लगता है कि आप शुरू से अपना कोड को फिर से लिखने की जानी चाहिए क्योंकि यह वास्तव में बदसूरत है। उचित इकाई परीक्षण, पीडीओ, सीएसआरएफ-सुरक्षा, ओओपी आदि

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