2013-10-18 8 views
6

मेरे पास मेरे पंजीकरण फॉर्म में एक फ़ील्ड है जिसमें उदाहरण के लिए name फ़ील्ड है, इसे user_name varchar(20) नामक फ़ील्ड में डेटाबेस में संग्रहीत किया जाएगा। यह स्पष्ट है कि मैं उपयोगकर्ता इनपुट सत्यापित करना चाहिए अगर मैं नीचे दिए गए कोड के साथ इस क्षेत्र frist मान्य:कौन सा पहले प्रदर्शन करना चाहिए? sanitizing या सत्यापन

<?php 
if(emptiy($_pos['name']) || strlen($_post['name'])>20) 
//send an not valid input error 
else{ 
$name=htmlspcialchars($_post['name']); 
//check for sql injection; 
//insert name into database;} 
?> 

एक उपयोगकर्ता <i> some one </i> की तरह एक नाम सम्मिलित करता है, तो स्ट्रिंग लंबाई 17 है ताकि कोई और हिस्सा performe जाएगा और नाम होगा &lt;i&gt some one &lt;/i&gt; जो लंबाई 28 है जो इस समय db.in में डालने के दौरान त्रुटि उत्पन्न करेगी यदि मैं उपयोगकर्ता को एक त्रुटि भेजता हूं कि उसका इनपुट बहुत लंबा है तो वह भ्रमित हो जाएगा। मुझे क्या करना चाहिए? सबसे अच्छा तरीका क्या है?

+5

आपको इसे संग्रहीत करने से पहले कभी भी डेटा एन्कोड नहीं करना चाहिए। इसे कच्चे स्टोर करें ('mysqli_real_escape_string' या इसी तरह की उचित से बचने का उपयोग करके) और इसे आउटपुट करने से पहले इसे एन्कोड करें। ऐसा इसलिए है क्योंकि यदि आप इसे HTML या JSON या किसी अन्य चीज़ के रूप में आउटपुट कर रहे हैं तो इसे अलग-अलग एन्कोडिंग की आवश्यकता होती है। –

+3

एसक्यूएल इंजेक्शन को रोकने के लिए सबसे अच्छी विधि डेटाबेस में डेटा डालने के लिए mysqli या PDO तैयार कथन का उपयोग करना है। @ [नाइट द डार्क एब्सोल] (http://stackoverflow.com/users/507674/niet-the-dark-absol) है सही लेकिन mysqli_real_escape_string() फ़ंक्शन को बहिष्कृत किया गया है। – nurakantech

+0

मैं कभी भी सुरक्षा कारणों से 'mysqli_real escape_string()' जैसे कार्यों का उपयोग नहीं करूंगा, मैं इसे और अधिक सुरक्षित बना रहा हूं। – naazanin

उत्तर

6

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

इसके साथ, आप परिणामों को मान्य करते हैं - क्या नाम पहले से ही इस्तेमाल किया गया है (अद्वितीय फ़ील्ड के लिए), क्या यह सही आकार है, क्या यह खाली नहीं है?

आपके द्वारा प्रदान किए जाने का कारण सटीक सही है - उपयोगकर्ता अनुभव को अधिकतम करने के लिए। उपयोगकर्ता को भ्रमित न करें, अगर आप इससे बच सकते हैं। यह गूंगा प्रति & पेस्ट व्यवहार से बचाने में मदद करता है, लेकिन आपको सावधान रहना होगा - अगर मैं अपना नाम "के $ एच @" के रूप में दर्ज करना चाहता हूं, तो मैं इसे "केह" में बदलने के साथ ठीक हो सकता हूं या नहीं।

दूसरा, यह भी बग को रोकने के लिए है।

क्या होता है जब आप ऐसे उपयोगकर्ता नाम बनाना चाहते हैं जो विशेष वर्णों की अनुमति न दें? अगर मैं "ब्रायन" दर्ज करता हूं, और आपका सिस्टम इसे पहले से उपयोग में नाम के रूप में अस्वीकार करता है, तो मैं "ब्रायन $" जमा करता हूं? सबसे पहले आप इसे मान्य करते हैं, और यह उपयोग में नहीं है, तो आप विशेष पात्रों को पट्टी करते हैं और आपको "ब्रायन" के साथ छोड़ दिया जाता है। ओह ओह - अब आपको या तो फिर से सत्यापित करना होगा, या आपको एक अजीब त्रुटि मिलेगी कि खाता निर्माण विफल हो गया है (यदि आपका डेटाबेस उदाहरण के लिए अद्वितीय उपयोगकर्ता नामों की आवश्यकता है), या इससे भी बदतर यह सफल होगा और अधिक लेखन/भ्रष्टाचार उपयोगकर्ता उपयोगकर्ता खातों के लिए होता है।

एक और उदाहरण न्यूनतम फ़ील्ड लंबाई है: यदि आपको कम से कम 3 अक्षरों की आवश्यकता होती है और केवल अक्षरों को स्वीकार करते हैं, और मैं "नहीं" दर्ज करता हूं तो आप इसे अस्वीकार कर देंगे; लेकिन अगर मैं "नहीं @ # $%" दर्ज करता हूं तो आप कह सकते हैं कि यह वैध था (लंबे समय तक पर्याप्त), इसे स्वच्छ करें, और अब यह मान्य नहीं है, आदि

इससे बचने का आसान तरीका पहले sanitize है , और फिर आपको सत्यापन के बारे में दोबारा सोचने की ज़रूरत नहीं है।

हालांकि, नाइट भंडारण से पहले डेटा एन्कोड करने के बारे में सही था; एचटीएमएल में आउटपुट को उचित रूप से एन्कोड किए जाने के रूप में आउटपुट सेट करना आम तौर पर आसान होता है, फिर इसे केवल डीकोड करना याद रखना होता है जब आप केवल सादे पाठ (टेक्स्ट बॉक्स में प्रवेश करने के लिए, JSON तारों आदि) चाहते हैं। आपके द्वारा उपयोग किए जाने वाले अधिकांश परीक्षण मामलों में HTML इकाइयों के साथ डेटा शामिल नहीं होगा, इसलिए आसानी से पकड़े गए मूर्खतापूर्ण बग को पेश करना आसान है।

बड़ी समस्या यह है कि जब ऐसी बग पेश की जाती है, तो यह आसानी से डेटा भ्रष्टाचार का कारण बन सकती है जिसे आसानी से हल नहीं किया जा सकता है। उदाहरण: आपके पास सादा पाठ है, इसे HTML फ़ील्ड के रूप में गलत तरीके से टेक्स्ट फ़ील्ड में आउटपुट करें, फ़ॉर्म वापस सबमिट हो जाता है और आप इसे फिर से एन्कोड करते हैं ... हर बार जब इसे खोला/पुनः सबमिट किया जाता है तो इसे फिर से एन्कोड किया जाता है। एक व्यस्त साइट/फॉर्म के साथ आप हजारों अलग-अलग एन्कोडेड प्रविष्टियों के साथ समाप्त हो सकते हैं, यह निर्धारित करने के लिए कोई स्पष्ट तरीका नहीं है कि एचटीएमएल एन्कोड किए जाने के लिए क्या और क्या नहीं था।

इंजेक्शन से सुरक्षा अच्छी है, लेकिन ऐसा करने के लिए HTML एन्कोडिंग डिज़ाइन नहीं किया गया है (और उस पर भरोसा नहीं किया जाना चाहिए)।

+0

ठीक के बीच कुछ रिक्त स्थान थे, मान लीजिए कि आप ब्रायन $ दर्ज करते हैं, पहले इसे स्वच्छ करें और परिणाम ब्रायन होगा, और इसे मान्य करें और यह अद्वितीय है, ठीक है आप पंजीकृत हैं और आप लॉग इन करना चाहते हैं, आप प्रवेश करना चाहते हैं ब्रायन और फिर लॉग इन फॉर्म में मैं इनपुट को sanitize shoulize? इसलिए यदि मुझे हेल्लो ब्रायन डालना चाहिए, और आप भ्रमित हो जाएंगे क्योंकि आपने ब्रायन $ – naazanin

+1

दर्ज किया है, तो आपको उपयोगकर्ता को यह जानना चाहिए कि आपको इनपुट को स्वच्छ करना है - मैं इस तरह की स्थिति में सुझाव देने के लिए भी कहूंगा जब आप इनपुट करते हैं कि यह अमान्य है तो आप उपयोगकर्ता को एक त्रुटि देते हैं। –

+0

@naazanin मैं gdscei से सहमत हूं, हालांकि आम तौर पर मैं इस तरह के niceties को क्लाइंट-साइड फॉर्म सत्यापन से पहले पोस्ट करने के लिए बचाता हूं। वहां मैं अमान्य आउटपुट के बारे में उपयोगकर्ता को संकेत देने के बारे में अधिक विनम्र हूं, जहां सर्वर-साइड पर मुझे दो मॉडल में से एक चुनने की अधिक संभावना है: 1) इसे काम करें और अगर उन्हें नहीं करना है तो उपयोगकर्ता को परेशान न करें पता है, या 2) अमान्य इनपुट को अस्वीकार करें और उपयोगकर्ता को यह पता लगाने दें कि क्या करना है। यह आपके उपयोग के मामले पर निर्भर करेगा, और मैं वैश्विक सुझाव नहीं दे सकता। आपका ऐप जितना अधिक अंतरराष्ट्रीय होगा, उतना ही सावधान रहेंगे कि आपको संभावित मान्य पात्रों को मना करने के बारे में अधिक जानकारी होगी। – BrianHall

2

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

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