PHP लॉगिन स्क्रिप्ट में कौन सी सर्वोत्तम प्रथाओं को नियोजित किया जाना चाहिए?


27

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

मैं PHP और एक MYSQL डेटाबेस का उपयोग किया जाएगा।

मैं md5 का उपयोग करता था, लेकिन मुझे लगता है कि sha256 या sha512 बेहतर होगा (सुरक्षित हैश और नमक के साथ)।

कुछ लॉगिन स्क्रिप्ट पूरे सत्र या यहां तक ​​कि उपयोगकर्ता एजेंट के आईपी पते को लॉग करते हैं, लेकिन मैं इससे बचना चाहता हूं क्योंकि यह प्रॉक्सी सर्वर के साथ संगत नहीं है।

मैं PHP 5 में सत्रों का उपयोग करने में सर्वोत्तम अभ्यास से थोड़ा पीछे हूं (पिछली बार जब मैंने PHP 4 पढ़ा था) तो इसके साथ कुछ सर्वोत्तम अभ्यास सहायक होंगे।

धन्यवाद।


1
अपनी स्क्रिप्ट को codereview.SE पर टॉस करें!
क्रिस '

@ क्रिस CodeReview कोड स्पष्टता और पसंद के साथ मदद करते हैं। आप निश्चित रूप से सुरक्षा के लिए उनके पास नहीं जाने वाले हैं। यदि कुछ भी हो, तो वे लगभग हमेशा आपको "अपना रोल" नहीं करने के लिए याद दिलाएंगे जो मूल रूप से एक ही उत्तर है क्योंकि वह एसई के लिए किसी भी प्रोग्रामिंग समुदाय में आने वाला है।
अल्टरनेटेक्स

जवाबों:


21

सबसे अच्छा लगता है कि पहिया को सुदृढ़ नहीं करना है। लेकिन, मैं समझता हूं, PHP की दुनिया में एक उच्च गुणवत्ता वाले घटक को खोजना मुश्किल हो सकता है जो पहले से ही करता है (यहां तक ​​कि मुझे पूरा यकीन है कि ऐसी चीजें लागू होती हैं और उनके कार्यान्वयन पहले से ही परीक्षण किए गए, ठोस, कोड-समीक्षा आदि हैं) )

यदि, कुछ कारणों से, आप एक रूपरेखा का उपयोग नहीं कर सकते हैं, तो यहां कुछ सुझाव दिए गए हैं:

सुरक्षा संबंधी सुझाव

  • यदि आप कर सकते हैं तो PBKDF2 या Bcrypt का उपयोग करें । उसके लिए किया है।

    औचित्य: दोनों एल्गोरिदम हैशिंग प्रक्रिया को मनमाने ढंग से धीमा कर सकते हैं, जो कि आप चाहते हैं कि जब हैशिंग पासवर्ड (तेज विकल्प आसान ब्रूट बल का मतलब हो)। आदर्श रूप से, आपको मापदंडों को समायोजित करना चाहिए ताकि प्रक्रिया एक ही हार्डवेयर पर समय के साथ धीमी और धीमी हो जाए, जबकि नया, तेज हार्डवेयर जारी किया जाता है।

  • यदि आप नहीं कर सकते हैं, तो कम से कम MD5 / SHA1 का उपयोग न करें। कभी नहीँ। इसके बारे में भूल जाओ । उदाहरण के लिए, इसके बजाय SHA512 का उपयोग करें। नमक का भी प्रयोग करें।

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

  • PHP में 5.5.0 और बाद में, का उपयोग करें password_hashऔर password_verify

    Rationale: फ्रेमवर्क द्वारा प्रदान किए गए फ़ंक्शन को कॉल करना आसान है, इसलिए गलती करने का जोखिम कम हो जाता है। उन दो कार्यों के साथ, आपको हैश जैसे विभिन्न मापदंडों के बारे में सोचने की ज़रूरत नहीं है। पहला फ़ंक्शन एक एकल स्ट्रिंग देता है जिसे तब डेटाबेस में संग्रहीत किया जा सकता है। दूसरा फ़ंक्शन पासवर्ड सत्यापन के लिए इस स्ट्रिंग का उपयोग करता है।

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

    प्रति घंटे की विफलताओं की सीमा निर्धारित करने के लिए एक और सुरक्षा होगी। यदि उपयोगकर्ता ने एक घंटे में 3600 गलत पासवर्ड दिए हैं, तो 1 पासवर्ड प्रति सेकंड, यह विश्वास करना मुश्किल है कि यह एक वैध उपयोगकर्ता है।

    Rationale: यदि आपके पासवर्ड असुरक्षित तरीके से हैंश किए गए हैं, तो brute force बहुत प्रभावी हो सकता है। यदि पासवर्ड सुरक्षित रूप से संग्रहीत किए जाते हैं, तो ब्रूट बल अभी भी आपके सर्वर के संसाधनों और नेटवर्क बैंडविड्थ को बर्बाद कर रहा है, जिससे वैध उपयोगकर्ताओं के लिए कम प्रदर्शन होता है। ब्रूट फोर्स डिटेक्शन को विकसित करना और सही करना आसान नहीं है, लेकिन किसी भी लेकिन छोटे सिस्टम के लिए, यह पूरी तरह से इसके लायक है।

  • हर चार सप्ताह में अपने उपयोगकर्ताओं से अपने पासवर्ड बदलने के लिए न कहें। यह अत्यंत कष्टप्रद है और सुरक्षा कम हो जाती है, क्योंकि यह पोस्ट-इट-आधारित सुरक्षा को प्रोत्साहित करती है।

    Rationale: यह विचार कि पासवर्ड को हर n सप्ताह में बदलने के लिए मजबूर करना सिस्टम को क्रूर बल से बचाता है, गलत है। ब्रूट बल के हमले आमतौर पर सेकंड, मिनट, घंटे या दिनों के भीतर सफल होते हैं, जो मासिक पासवर्ड परिवर्तन को अप्रासंगिक बनाता है। दूसरी ओर, उपयोगकर्ता पासवर्ड याद रखने में बुरे हैं। यदि, इसके अलावा, उन्हें बदलने की आवश्यकता है, तो वे या तो बहुत ही सरल पासवर्ड का उपयोग करने का प्रयास करेंगे या बस इसके बाद अपने पासवर्ड को नोट करेंगे।

  • हर बार, सबका ऑडिट करें। लॉगऑन स्टोर करें, लेकिन ऑडिट लॉग में पासवर्ड स्टोर न करें। सुनिश्चित करें कि ऑडिट लॉग को संशोधित नहीं किया जा सकता है (यानी आप अंत में डेटा जोड़ सकते हैं, लेकिन मौजूदा डेटा को संशोधित नहीं कर सकते हैं)। सुनिश्चित करें कि ऑडिट लॉग नियमित बैकअप के अधीन हैं। आदर्श रूप से, लॉग्स को एक समर्पित सर्वर पर बहुत प्रतिबंधक एक्सेस के साथ संग्रहीत किया जाना चाहिए: यदि किसी अन्य सर्वर को हैक किया जाता है, तो हमलावर अपनी उपस्थिति (और हमले के दौरान लिए गए पथ) को छिपाने के लिए लॉग्स को मिटा नहीं पाएगा।

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

उपयोग के सुझावों में आसानी

  • उपयोगकर्ता को पासवर्ड याद रखना चाहिए अगर वह चाहती है, भले ही अधिकांश ब्राउज़र पहले से ही यह सुविधा हो।
  • उपयोगकर्ता नाम और पासवर्ड के लिए पूछने के बजाय Google दृष्टिकोण का उपयोग न करें, उपयोगकर्ता से कभी-कभी केवल पासवर्ड के लिए पूछा जाता है , उपयोगकर्ता नाम पहले से ही एक में दिखाया जा रहा है <span/>। ब्राउज़र इस मामले में पासवर्ड फ़ील्ड नहीं भर सकते हैं (कम से कम फ़ायरफ़ॉक्स ऐसा नहीं कर सकता है), इसलिए यह लॉगऑफ़ करने के लिए मजबूर करता है, फिर ब्राउज़र द्वारा भरा एक साधारण फॉर्म के साथ लॉगऑन करने के लिए।
  • लॉगऑन के लिए जावास्क्रिप्ट-सक्षम पॉपअप का उपयोग न करें । यह ब्राउज़र्स पासवर्ड-याद सुविधाओं को तोड़ता है (और सभी मामलों में बेकार है)।
  • उपयोगकर्ता को उसका उपयोगकर्ता नाम या उसका मेल पता दर्ज करने दें । जब मैं पंजीकरण करता हूं, तो कभी-कभी उपयोगकर्ता नाम जिसे मैं दर्ज करना चाहता हूं, पहले से ही लिया जाता है, इसलिए मुझे एक नया आविष्कार करना होगा। मेरे पास दो घंटे में यह नाम भूलने की पूरी संभावना है।
  • लॉगऑन फॉर्म के पास हमेशा "मेरे पासवर्ड को भूल जाओ" लिंक रखें । इसे केवल तभी प्रदर्शित न करें जब उपयोगकर्ता लॉग ऑन करने में विफल रहा: जिस उपयोगकर्ता को अपना पासवर्ड याद नहीं है, उसे इस बात का कोई अंदाजा नहीं है कि उसे "मेरा पासवर्ड भूल गए" लिंक देखने के लिए एक गलत एक सबमिट करना होगा।
  • सुरक्षा का उपयोग डाक द्वारा न करें ।
  • पासवर्ड से संबंधित मूर्खतापूर्ण नियमों का आविष्कार न करें ताकि इसे कमजोर बनाया जा सके । उदाहरण: "आपका पासवर्ड लोअरकेस अक्षर से शुरू होना चाहिए।" "आपके पासवर्ड में स्थान नहीं हो सकते।"

Bcrypt में नहीं आया। क्या सिफारिश करने के लिए आपका तर्क है? Md5 / sha1 क्यों नहीं? बाकी सुझावों के लिए धन्यवाद!
बैरीटोनुक

तर्क सरल है: bcryptउन लोगों द्वारा किया जाता है जो उच्च योग्य हैं। इसका परीक्षण, समीक्षा इत्यादि भी की जाती है, इसलिए स्वयं उसी चीज को लागू करने का कोई कारण नहीं है। यह आपकी वेबसाइट के लिए अपनी खुद की क्रिप्टोग्राफी एल्गोरिदम बनाने जैसा है। * "
Md5

5
bcrypt धीमा है और जैसा कि पेशेवरों द्वारा कार्यान्वित किया गया है। md5 एक हैशिंग एल्गोरिथ्म है जो एक एन्क्रिप्शन नहीं है जो काफी समान चीज नहीं है। किसी फाइल को फास्ट करना अच्छा है, md5 का उपयोग यहां किया जाएगा ... हैशिंग के पासवर्ड की इतनी तेज आवश्यकता नहीं है, bcrypt यहां मदद कर सकता है। कारण मैं यह कहता हूं कि क्रिप्ट एल्गोरिथ्म "धीमा" होने पर जानवर बल अधिक कठिन हो जाता है।
क्रिस

2
@baritoneuk: न्यूनतम ठंडा है। लेकिन मैं यह नहीं गिन सकता कि मेरे पास कितनी साइटें हैं जिनमें अधिकतम लंबाई, कोई गैर-अल्फ़ान्यूमेरिक वर्ण, आदि जैसे प्रतिबंध नहीं थे, यदि आप वैसे भी पासवर्ड को हैश करने जा रहे हैं - जिससे मुझे चिंता होती है कि वे नहीं हैं , वे इसे स्पष्ट रूप से अपने डेटाबेस में संग्रहीत कर रहे हैं।
कार्सन 63000

1
@ ब्रायन ऑर्टिज़: हमेशा नहीं। कभी-कभी एक सीमा निर्धारित करना एक अच्छा विचार है। यदि आप ऐसा नहीं करते हैं, तो क्या आप परीक्षण करते हैं कि क्या आपका आवेदन किसी भी लम्बाई के लिए काम करता है? कैसे? यदि आप इसका परीक्षण नहीं करते हैं, तो यदि आप काम कर रहे हैं तो आप कैसे सुनिश्चित कर सकते हैं? इसके बजाय, एक उचित मूल्य की सीमा निर्धारित करते समय, 100 की तरह, आप 100 वर्णों के पासवर्ड के लिए आसानी से परीक्षण कर सकते हैं।
आर्सेनी मूरज़ेंको

6
  1. आपकी साइट को HTTPS का उपयोग करना चाहिए बिना किसी बिंदु पर आपको एक लॉगिन पृष्ठ प्रस्तुत करना चाहिए या गैर-एन्क्रिप्टेड कनेक्शन से लॉगिन स्वीकार करना चाहिए।
  2. यदि आप HTTPS का उपयोग करते हैं तो आपके कुकीज़ को केवल HTTP तक ही सीमित रखा जाना चाहिए और सुरक्षित कनेक्शन तक सीमित रखा जाना चाहिए ।
  3. लॉगिन प्रक्रिया को 2 सेकंड से कम नहीं लेना चाहिए (1 यदि आपको लगता है कि 2 सेकंड बहुत लंबा है)। पासवर्ड को संग्रहीत और सत्यापित करते समय एक सुरक्षित हैश का उपयोग करें , और एक नमक का उपयोग करें जो अनुमान लगाने में कठिन है। bcryptयदि संभव हो तो उपयोग करें । अन्यथा, किसी अन्य प्रकार के पुनरावृत्त हैश का उपयोग करें।
  4. कभी भी किसी भी तरह से अपने डेटाबेस प्रश्नों की रचना न करें, जैसे कार्यों का उपयोग करने की आवश्यकता होती है mysql_real_escape_string। अपनी क्वेरी को तैयार करने के लिए स्ट्रिंग स्ट्रिंग का उपयोग कभी न करें। तैयार, पैराड्राइज्ड प्रश्नों का उपयोग करें। अधिकांश, यदि सभी नहीं, तो PHP के लिए DB ड्राइवर इसका समर्थन करते हैं। आप इसे कैसे करना नहीं जानते हैं, कैसे कुछ समय सीखने खर्च करने के लिए prepare, bindऔर executeका उपयोग कर जो भी डीबी आप उपयोग कर रहे। यह एसक्यूएल इंजेक्शन के खिलाफ खुद को बचाने का एकमात्र निश्चित तरीका है। पीडीओ इसका समर्थन करता है।
  5. अपने उपयोगकर्ताओं को उनके ईमेल के लिए उपयोग किए जाने वाले पासवर्ड का उपयोग करने के लिए प्रोत्साहित करें । उन्हें याद दिलाएं कि यदि आपकी साइट से छेड़छाड़ की जाती है और यदि वे दोनों जगहों पर एक ही पासवर्ड का उपयोग करते हैं, तो कोई व्यक्ति उनके ईमेल को हाईजैक कर सकता है।

HTTPS के लिए +1, चूंकि सार्वजनिक वाईफाई नेटवर्क के माध्यम से अधिक से अधिक ट्रैफ़िक है। लेकिन मैं उपयोगकर्ताओं के दृष्टिकोण से बिंदु 3: 2 सेकंड से बहुत अधिक असहमत हूं। 0.5 एस। बस ठीक है, खासकर अगर अन्य एंटी-ब्रूट-बल तकनीकों का उपयोग किया जाता है।
आर्सेनी मूरज़ेंको

मैं # 4 नंबर पर भ्रमित हूं। आप mysql_real_escape_string के साथ डेटा से बचने के सम्मेलन से कैसे बच सकते हैं? सभी उपयोगकर्ता द्वारा प्रस्तुत डेटा पर भरोसा नहीं किया जाना चाहिए और तदनुसार फ़िल्टर किया जाना चाहिए।
chrisw

@chrisw: हाँ, सभी उपयोगकर्ता इनपुट को ऐसे संभाला जाना चाहिए जैसे कि यह दुर्भावनापूर्ण है। लेकिन जब आप पैराड्राइज्ड प्रश्नों का उपयोग करते हैं, तो यह, कोई नहीं, एसक्यूएल इंजेक्शन को रोकने का सबसे अच्छा तरीका है । यदि आप तैयार और पैराड्राइज्ड प्रश्नों का उपयोग नहीं कर रहे हैं, तो आप SQL इंजेक्शन के लिए असुरक्षित हैं। mysql_real_escape_stringझूठी सुरक्षा है - यह कोई गारंटी नहीं है। पैरामीट्रिक प्रश्न हैं।
ग्रेफेड

मैं इसमें कुछ आगे पढ़ने के बाद अब सहमत हूं। फ़ंक्शन: mysql_real_escape_string आमतौर पर अधिकांश भाग के लिए सुरक्षित है, मैं इसे एक बड़ी देयता नहीं मानूंगा, लेकिन मैं देख सकता हूं कि कैसे तैयार किए गए बयानों का उपयोग करना अधिक कुशल है।
chrisw

1
आप पीडीओ का उपयोग कर सकते हैं।
फेलिक्स जी

1

नमकीन वन-वे हैश (अधिमानतः SHA512 http://au2.php.net/manual/en/function.hash.php ) का उपयोग करें ... इस तरह, अगर कोई आपके डेटाबेस को हैक करता है, भले ही वे नमक जानते हों , वे पासवर्ड नहीं निकाल सकते (एक इंद्रधनुष तालिका के बिना, जो SHA512 के लिए ढीले होंगे)।

HTTPS का उपयोग करें।

उपयोगकर्ता नाम / पासवर्ड की पुष्टि ईमेल के माध्यम से वापस न भेजें, जब वे पंजीकरण करें।

यदि आप 'मुझे याद रखें' के लिए कुकीज़ की अनुमति देते हैं - प्रशासन और प्रोफ़ाइल संपादन कार्यों तक पहुंचने के लिए एक अतिरिक्त लॉगिन जोड़ें।

यदि किसी उपयोगकर्ता को पासवर्ड गलत मिलता है, तो यह न कहें कि उन्हें पासवर्ड गलत मिला है (जैसे कि उन्हें 'उपयोगकर्ता नाम या पासवर्ड गलत मिला है') - इस प्रकार, वैध उपयोगकर्ता नाम क्या हैं, इस पर कम सुराग।

स्क्रीन नाम बनाम लॉगिन की कोशिश करें और लागू करें - इस तरह, उपयोगकर्ता लिस्टिंग पर कम उपयोगकर्ता अपना लॉगिन नाम प्रदर्शित करेंगे।


ईमेल द्वारा सादे पाठ में ईमेल न भेजने के बारे में बिट से पूरी तरह सहमत हैं। मैं वेब साइटों को ऐसा करने के समय की गिनती खो दिया है। यदि आपके पास सभी साइटों के लिए 1 पासवर्ड है (जो सौभाग्य से मैं नहीं हूं) तो संभावित रूप से सभी वेबसाइटों से समझौता किया जाता है। ऐसी वेबसाइट शायद सादा पाठ में भी पासवर्ड संग्रहीत करती हैं। sigh
baritoneuk

1
  • MD5 या SHA1 हैशिंग एल्गोरिदम का उपयोग कभी न करें। हमेशा SHA512 की तरह नए लोगों से चिपके रहें
  • हमेशा एक मजबूत यादृच्छिक उत्पन्न नमक का उपयोग करें
  • "पासवर्ड भूल गए" के मामले में भी कभी भी अपने उपयोगकर्ताओं को अपना पासवर्ड न भेजें।
  • Mysql_ * फ़ंक्शन का उपयोग कभी न करें। वे लंबे समय तक अवमूल्यन कर रहे हैं। पीडीओ से चिपके रहे
  • पासवर्ड को कभी भी सत्र या कुकीज़ में न रखें

0

यहां एक सलाह दी गई है: सुनिश्चित करें कि चोरी रोकने के लिए आपके कुकीज़ को JS के साथ एक्सेस नहीं किया जा सकता है, अपने कुकीज़ की सुरक्षा देखें : Jeff Atwood द्वारा HttpOnly लेख

... चतुर निर्माण के माध्यम से, विकृत URL केवल सैनिटाइज़र के पिछले हिस्से का प्रबंधन करता है। अंतिम रेंडर कोड, जब ब्राउज़र में देखा जाता है, उस रिमोट सर्वर से स्क्रिप्ट को लोड और निष्पादित करता है।

... जो कोई भी इस स्क्रिप्ट-इन-इंजेक्ट किए गए उपयोगकर्ता प्रोफ़ाइल पृष्ठ को लोड करता है, उसने अनजाने में अपने ब्राउज़र कुकीज़ को एक दुष्ट दूरस्थ सर्वर पर प्रसारित कर दिया है!

जैसा कि हम पहले ही स्थापित कर चुके हैं, एक बार जब किसी के पास किसी वेबसाइट के लिए आपके ब्राउज़र कुकीज़ होते हैं, तो वे अनिवार्य रूप से आपकी पहचान के लिए राज्य की कुंजी रखते हैं ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.