"मुझे लॉग इन रखें" - सबसे अच्छा तरीका


257

मेरा वेब एप्लिकेशन उपयोगकर्ता के बारे में जानकारी संग्रहीत करने के लिए सत्रों का उपयोग करता है, जब वे लॉग इन करते हैं, और उस जानकारी को बनाए रखने के लिए जैसे वे ऐप के भीतर पृष्ठ से पृष्ठ पर जाते हैं। इस विशिष्ट आवेदन में, मैं भंडारण कर रहा हूँ user_id, first_nameऔर last_nameव्यक्ति की।

मैं लॉग ऑन ऑन में "कीप मी लॉग इन" विकल्प की पेशकश करना चाहता हूं, जो दो सप्ताह के लिए उपयोगकर्ता की मशीन पर एक कुकी डाल देगा, जो ऐप में वापस आने पर उसी विवरण के साथ अपने सत्र को फिर से शुरू करेगा।

ऐसा करने के लिए सबसे अच्छा तरीका क्या है? मैं उन्हें user_idकुकी में संग्रहीत नहीं करना चाहता , क्योंकि ऐसा लगता है कि इससे एक उपयोगकर्ता के लिए दूसरे उपयोगकर्ता की पहचान करने की कोशिश करना आसान हो जाएगा।

जवाबों:


735

ठीक है, मुझे यह स्पष्ट रूप से बताने दें: यदि आप उपयोगकर्ता डेटा, या उपयोगकर्ता डेटा से प्राप्त कुछ भी इस उद्देश्य के लिए कुकी में डाल रहे हैं, तो आप कुछ गलत कर रहे हैं।

वहाँ। यह मैंने कहा था। अब हम वास्तविक उत्तर पर आगे बढ़ सकते हैं।

हैशिंग उपयोगकर्ता डेटा में क्या गलत है, आप पूछें? खैर, यह अस्पष्टता के माध्यम से सतह और सुरक्षा के संपर्क में आता है।

एक दूसरे के लिए कल्पना कीजिए कि आप हमलावर हैं। आप अपने सत्र में याद करने के लिए एक क्रिप्टोग्राफ़िक कुकी सेट देखें। यह 32 अक्षर चौड़ा है। जी। यह एक MD5 हो सकता है ...

आइए एक दूसरे के लिए भी कल्पना करें कि वे उस एल्गोरिथ्म को जानते हैं जो आपने उपयोग किया था। उदाहरण के लिए:

md5(salt+username+ip+salt)

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

संक्षेप में, आपकी रक्षा करने वाली एकमात्र चीज नमक है, जो वास्तव में आपकी रक्षा नहीं कर रही है जितना आप सोचते हैं।

लेकिन रुकें!

उस सभी की भविष्यवाणी की गई थी कि हमलावर एल्गोरिदम जानता है! यदि यह गुप्त और भ्रामक है, तो आप सुरक्षित हैं, है ना? गलत । सोच की उस लाइन का एक नाम है: सिक्योरिटी थ्रू ऑब्सुरिटी , जिस पर कभी भरोसा नहीं करना चाहिए ।

बेहतर तरीका है

बेहतर तरीका यह है कि यूजर की जानकारी को कभी भी सर्वर को न छोड़ें, केवल आईडी को छोड़कर।

जब उपयोगकर्ता लॉग इन करता है, तो एक बड़ा (128 से 256 बिट) यादृच्छिक टोकन उत्पन्न करें। उस डेटाबेस तालिका में जोड़ें, जो उपयोगकर्ता के लिए टोकन मैप करती है, और फिर इसे क्लाइंट को कुकी में भेजती है।

क्या होगा यदि हमलावर किसी अन्य उपयोगकर्ता के यादृच्छिक टोकन का अनुमान लगाता है?

अच्छा, चलो यहाँ कुछ गणित करते हैं। हम एक 128 बिट यादृच्छिक टोकन उत्पन्न कर रहे हैं। इसका मतलब है कि वहाँ हैं:

possibilities = 2^128
possibilities = 3.4 * 10^38

अब, यह दिखाने के लिए कि यह संख्या कितनी बेतुकी है, आइए इंटरनेट पर हर सर्वर की कल्पना करें (चलो आज 50,000,000 कहते हैं) उस संख्या को प्रत्येक सेकंड 1,000,000,000 की दर से बल देने की कोशिश कर रहे हैं। वास्तव में आपके सर्वर ऐसे लोड के तहत पिघल जाएंगे, लेकिन चलो इसे खेलते हैं।

guesses_per_second = servers * guesses
guesses_per_second = 50,000,000 * 1,000,000,000
guesses_per_second = 50,000,000,000,000,000

तो 50 क्वाड्रिलियन प्रति सेकंड का अनुमान है। वह तेज है! सही?

time_to_guess = possibilities / guesses_per_second
time_to_guess = 3.4e38 / 50,000,000,000,000,000
time_to_guess = 6,800,000,000,000,000,000,000

तो 6.8 sextillion सेकंड ...

आइए इसे और अधिक अनुकूल संख्या में लाने का प्रयास करें।

215,626,585,489,599 years

या इससे भी बेहतर:

47917 times the age of the universe

हाँ, यह ब्रह्मांड की आयु का 47917 गुना है ...

असल में, यह फटा नहीं जा रहा है।

इसलिए योग करने के लिए:

बेहतर तरीका जो मैं सुझाता हूं वह कुकी को तीन भागों के साथ संग्रहीत करना है।

function onLogin($user) {
    $token = GenerateRandomToken(); // generate a token, should be 128 - 256 bit
    storeTokenForUser($user, $token);
    $cookie = $user . ':' . $token;
    $mac = hash_hmac('sha256', $cookie, SECRET_KEY);
    $cookie .= ':' . $mac;
    setcookie('rememberme', $cookie);
}

फिर, मान्य करने के लिए:

function rememberMe() {
    $cookie = isset($_COOKIE['rememberme']) ? $_COOKIE['rememberme'] : '';
    if ($cookie) {
        list ($user, $token, $mac) = explode(':', $cookie);
        if (!hash_equals(hash_hmac('sha256', $user . ':' . $token, SECRET_KEY), $mac)) {
            return false;
        }
        $usertoken = fetchTokenByUserName($user);
        if (hash_equals($usertoken, $token)) {
            logUserIn($user);
        }
    }
}

नोट: उपयोगकर्ता और टोकन के संयोजन का उपयोग न करें और अपने डेटाबेस में रिकॉर्ड देखने के लिए टोकन। हमेशा उपयोगकर्ता के आधार पर एक रिकॉर्ड प्राप्त करना सुनिश्चित करें और बाद में प्राप्त टोकन की तुलना करने के लिए एक समय-सुरक्षित तुलना फ़ंक्शन का उपयोग करें। समय हमलों के बारे में अधिक

अब, यह बहुत महत्वपूर्ण है कि SECRET_KEYएक क्रिप्टोग्राफिक रहस्य ( /dev/urandomकिसी उच्च-एन्ट्रापी इनपुट से उत्पन्न और / या व्युत्पन्न कुछ द्वारा उत्पन्न ) हो। इसके अलावा, GenerateRandomToken()एक मजबूत यादृच्छिक स्रोत होने की आवश्यकता है ( mt_rand()लगभग इतना मजबूत नहीं है। एक पुस्तकालय का उपयोग करें, जैसे कि randomLib या random_compat , या के mcrypt_create_iv()साथ DEV_URANDOM...)

hash_equals()रोकने के लिए है समय हमलों । यदि आप PHP 5.6 के नीचे PHP संस्करण का उपयोग करते हैं, तो फ़ंक्शन hash_equals()समर्थित नहीं है। इस स्थिति में आप hash_equals()टाइमसेफ़.कॉम फ़ंक्शन को बदल सकते हैं :

/**
 * A timing safe equals comparison
 *
 * To prevent leaking length information, it is important
 * that user input is always used as the second parameter.
 *
 * @param string $safe The internal (safe) value to be checked
 * @param string $user The user submitted (unsafe) value
 *
 * @return boolean True if the two strings are identical.
 */
function timingSafeCompare($safe, $user) {
    if (function_exists('hash_equals')) {
        return hash_equals($safe, $user); // PHP 5.6
    }
    // Prevent issues if string length is 0
    $safe .= chr(0);
    $user .= chr(0);

    // mbstring.func_overload can make strlen() return invalid numbers
    // when operating on raw binary strings; force an 8bit charset here:
    if (function_exists('mb_strlen')) {
        $safeLen = mb_strlen($safe, '8bit');
        $userLen = mb_strlen($user, '8bit');
    } else {
        $safeLen = strlen($safe);
        $userLen = strlen($user);
    }

    // Set the result to the difference between the lengths
    $result = $safeLen - $userLen;

    // Note that we ALWAYS iterate over the user-supplied length
    // This is to prevent leaking length information
    for ($i = 0; $i < $userLen; $i++) {
        // Using % here is a trick to prevent notices
        // It's safe, since if the lengths are different
        // $result is already non-0
        $result |= (ord($safe[$i % $safeLen]) ^ ord($user[$i]));
    }

    // They are only identical strings if $result is exactly 0...
    return $result === 0;
}

7
लेकिन क्या इस दृष्टिकोण का अर्थ यह नहीं है कि कोई भी इस उपयोगकर्ता नाम और कुकी को ले सकता है और किसी अन्य डिवाइस से इस उपयोगकर्ता के रूप में लॉग इन कर सकता है?
सरल

8
योग्य :-), ध्यान दें कि 47917 वर्ष अनुमान लगाने का अधिकतम समय है, यादृच्छिक टोकन का अनुमान 1 घंटे में भी लगाया जा सकता है।
तूफान_बस्टर

33
यह अजीब है क्योंकि आपका कोड आपके उत्तर का खंडन करता है। आप कहते हैं "यदि आप एक कुकी में उपयोगकर्ता डेटा डाल रहे हैं [...] आप कुछ गलत कर रहे हैं", लेकिन यह वही है जो आपका कोड कर रहा है! क्या कुकी से उपयोगकर्ता नाम को निकालना बेहतर नहीं है, केवल टोकन पर हैश की गणना करें (और शायद कुकी चोरी को रोकने के लिए आईपी पता जोड़ें) और उसके बाद fetchUsernameByToken के बजाय fetchTokenBusUserName याद में () करें?
लेवेन

9
PHP 5.6 के बाद से, स्ट्रिंग की तुलना करते समय समय के हमलों को रोकने के लिए hash_equals का उपयोग किया जा सकता है।
23:21 पर F21

5
@ यह किसी को एक वैध टोकन लेने से रोकता है, और इसके साथ जुड़े उपयोगकर्ता को बदलना।
ircmaxell

93

सुरक्षा सूचना : नियतात्मक डेटा के एमडी 5 हैश से कुकी को बंद करना एक बुरा विचार है; CSPRNG से प्राप्त रैंडम टोकन का उपयोग करना बेहतर है। अधिक सुरक्षित दृष्टिकोण के लिए इस प्रश्न का उत्तर ircmaxell देखें ।

आमतौर पर मैं ऐसा कुछ करता हूं:

  1. उपयोगकर्ता लॉग इन 'मुझे लॉग इन रखें' के साथ
  2. सत्र बनाएँ
  3. SOMETHING नामक कुकी बनाएँ: md5 (नमक + उपयोगकर्ता नाम + ip + नमक) और कुकी जिसे id कहा जाता है।
  4. डेटाबेस में कुकी स्टोर करें
  5. उपयोगकर्ता सामान और पत्ते करता है ----
  6. उपयोगकर्ता रिटर्न, किसी चीज़ की कुकी की जांच करें, यदि यह मौजूद है, तो उस उपयोगकर्ता के लिए डेटाबेस से पुरानी हैश प्राप्त करें, डेटाबेस से हैश के साथ कुकी सोमिंग मैच की सामग्री की जांच करें, जो एक नए गणना के साथ मेल भी करना चाहिए (के लिए) आईपी) इस प्रकार: कुकीहैश == डेटाबेसहैश == md5 (नमक + उपयोगकर्ता नाम + आईपी + नमक), अगर वे करते हैं, तो गोटो 2, अगर वे गोटो नहीं हैं 1

निश्चित रूप से आप विभिन्न कुकी नामों आदि का उपयोग कर सकते हैं। आप कुकी की सामग्री को थोड़ा बदल सकते हैं, बस यह सुनिश्चित करें कि यह आसानी से निर्मित न हो। आप उदाहरण के लिए उपयोगकर्ता बनाते समय user_salt भी बना सकते हैं और कुकी में भी डाल सकते हैं।

इसके अलावा आप md5 के बजाय sha1 का उपयोग कर सकते हैं (या बहुत अधिक किसी भी एल्गोरिथ्म)


30
IP को हैश में क्यों शामिल किया गया है? इसके अलावा, कुकी में टाइमस्टैम्प जानकारी शामिल करना सुनिश्चित करें और कुकी के लिए अधिकतम आयु स्थापित करने के लिए इस जानकारी का उपयोग करें ताकि आप एक पहचान टोकन नहीं बना रहे हैं जो अनंत काल के लिए अच्छा है।
स्कॉट मिशेल

4
@ अभिषेक दिलीवाल: यह एक बहुत पुराना धागा है, लेकिन मुझे मैथ्यू के समान उत्तर की तलाश थी। मुझे नहीं लगता कि सेशन_आईडी Pim के जवाब के लिए काम करेगा क्योंकि आप db हैश, कुकी हैश और करंट सेशन_ID को चेक नहीं कर सकते क्योंकि session_ID हर सेशन_स्टार्ट () को बदल देता है; मैंने सोचा था कि मैं इसे इंगित करता हूँ।
भाग

3
मैं सुस्त होने के लिए माफी चाहता हूँ, लेकिन दूसरी कुकी someELSE का उद्देश्य क्या है? इस मामले में आईडी क्या है? क्या यह इंगित करने के लिए "सही / गलत" मूल्य का एक सरल प्रकार है कि क्या उपयोगकर्ता मुझे लॉग इन सुविधा का उपयोग करना चाहता है? यदि हां, तो यह देखने के लिए कि कुकी कुकी प्रथम स्थान पर मौजूद है या नहीं, क्यों नहीं देखा गया? यदि उपयोगकर्ता अपने लॉगिन को जारी नहीं रखना चाहता है, तो SOMETHING कुकी पहले स्थान पर नहीं होगी? अंत में, क्या आप हैश को फिर से गतिशील रूप से उत्पन्न कर रहे हैं और सुरक्षा के अतिरिक्त उपाय के रूप में कुकी और डीबी के खिलाफ जांच कर रहे हैं?
इसकाmequinn

4
टोकन रैंडम होना चाहिए, किसी भी तरह से उपयोगकर्ता / उसके आईपी / उसके उपयोगकर्ता के साथ / कुछ भी नहीं जुड़ा होना चाहिए। यह प्रमुख सुरक्षा दोष है।
पैमिल

4
आप दो लवणों का उपयोग क्यों करते हैं? md5 (नमक + उपयोगकर्ता नाम + आईपी + नमक)
हारून क्रेडर

77

परिचय

आपका शीर्षक "कीप मी लॉग इन" - सबसे अच्छा दृष्टिकोण मेरे लिए यह जानना मुश्किल बना देता है कि कहां से शुरू करें क्योंकि यदि आप सबसे अच्छा दृष्टिकोण देख रहे हैं तो आपको निम्नलिखित पर विचार करना होगा:

  • पहचान
  • सुरक्षा

कुकीज़

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

बूल सेटकुकी (स्ट्रिंग $ नाम [, स्ट्रिंग $ मूल्य [, इंट $ एक्सपायर = 0], स्ट्रिंग $ पथ [, स्ट्रिंग $ डोमेन [, बूल $ सुरक्षित = गलत [, बूल $ httponly = false]]]]]]]

  • सुरक्षित (HTTPS कनेक्शन का उपयोग करके)
  • httponly (XSS हमले के माध्यम से पहचान की चोरी को कम करें)

परिभाषाएं

  • टोकन (एन लंबाई का अप्रत्याशित रैंडम स्ट्रिंग जैसे। / देव / यूरेनियम)
  • संदर्भ (एन लंबाई के अप्रत्याशित यादृच्छिक स्ट्रिंग जैसे / देव / यूरेनियम)
  • हस्ताक्षर (HMAC विधि का उपयोग कर एक महत्वपूर्ण हैश मान उत्पन्न करें)

सरल दृष्टिकोण

एक सरल समाधान होगा:

  • उपयोगकर्ता मुझे याद रखें के साथ लॉग ऑन है
  • लॉगिन कुकी टोकन और हस्ताक्षर के साथ जारी किया गया
  • जब वापस आ रहा है, तो हस्ताक्षर की जाँच की जाती है
  • यदि हस्ताक्षर ठीक है .. तो उपयोगकर्ता नाम और टोकन डेटाबेस में देखा जाता है
  • यदि मान्य नहीं है .. तो लॉगिन पृष्ठ पर लौटें
  • यदि मान्य स्वचालित रूप से लॉगिन है

उपरोक्त मामले का अध्ययन इस पृष्ठ पर दिए गए सभी उदाहरणों को संक्षेप में प्रस्तुत करता है लेकिन वे नुकसान हैं

  • यह जानने का कोई तरीका नहीं है कि कुकीज़ चुराई गई थीं या नहीं
  • हमलावर संवेदनशील संचालन जैसे पासवर्ड या डेटा को बदलना जैसे व्यक्तिगत और बेकिंग जानकारी आदि तक पहुंच सकता है।
  • समझौता किया गया कुकी अभी भी कुकी जीवन काल के लिए मान्य होगा

बेहतर समाधान

एक बेहतर समाधान होगा

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

उदाहरण कोड

// Set privateKey
// This should be saved securely 
$key = 'fc4d57ed55a78de1a7b31e711866ef5a2848442349f52cd470008f6d30d47282';
$key = pack("H*", $key); // They key is used in binary form

// Am Using Memecahe as Sample Database
$db = new Memcache();
$db->addserver("127.0.0.1");

try {
    // Start Remember Me
    $rememberMe = new RememberMe($key);
    $rememberMe->setDB($db); // set example database

    // Check if remember me is present
    if ($data = $rememberMe->auth()) {
        printf("Returning User %s\n", $data['user']);

        // Limit Acces Level
        // Disable Change of password and private information etc

    } else {
        // Sample user
        $user = "baba";

        // Do normal login
        $rememberMe->remember($user);
        printf("New Account %s\n", $user);
    }
} catch (Exception $e) {
    printf("#Error  %s\n", $e->getMessage());
}

कक्षा का उपयोग किया

class RememberMe {
    private $key = null;
    private $db;

    function __construct($privatekey) {
        $this->key = $privatekey;
    }

    public function setDB($db) {
        $this->db = $db;
    }

    public function auth() {

        // Check if remeber me cookie is present
        if (! isset($_COOKIE["auto"]) || empty($_COOKIE["auto"])) {
            return false;
        }

        // Decode cookie value
        if (! $cookie = @json_decode($_COOKIE["auto"], true)) {
            return false;
        }

        // Check all parameters
        if (! (isset($cookie['user']) || isset($cookie['token']) || isset($cookie['signature']))) {
            return false;
        }

        $var = $cookie['user'] . $cookie['token'];

        // Check Signature
        if (! $this->verify($var, $cookie['signature'])) {
            throw new Exception("Cokies has been tampared with");
        }

        // Check Database
        $info = $this->db->get($cookie['user']);
        if (! $info) {
            return false; // User must have deleted accout
        }

        // Check User Data
        if (! $info = json_decode($info, true)) {
            throw new Exception("User Data corrupted");
        }

        // Verify Token
        if ($info['token'] !== $cookie['token']) {
            throw new Exception("System Hijacked or User use another browser");
        }

        /**
         * Important
         * To make sure the cookie is always change
         * reset the Token information
         */

        $this->remember($info['user']);
        return $info;
    }

    public function remember($user) {
        $cookie = [
                "user" => $user,
                "token" => $this->getRand(64),
                "signature" => null
        ];
        $cookie['signature'] = $this->hash($cookie['user'] . $cookie['token']);
        $encoded = json_encode($cookie);

        // Add User to database
        $this->db->set($user, $encoded);

        /**
         * Set Cookies
         * In production enviroment Use
         * setcookie("auto", $encoded, time() + $expiration, "/~root/",
         * "example.com", 1, 1);
         */
        setcookie("auto", $encoded); // Sample
    }

    public function verify($data, $hash) {
        $rand = substr($hash, 0, 4);
        return $this->hash($data, $rand) === $hash;
    }

    private function hash($value, $rand = null) {
        $rand = $rand === null ? $this->getRand(4) : $rand;
        return $rand . bin2hex(hash_hmac('sha256', $value . $rand, $this->key, true));
    }

    private function getRand($length) {
        switch (true) {
            case function_exists("mcrypt_create_iv") :
                $r = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
                break;
            case function_exists("openssl_random_pseudo_bytes") :
                $r = openssl_random_pseudo_bytes($length);
                break;
            case is_readable('/dev/urandom') : // deceze
                $r = file_get_contents('/dev/urandom', false, null, 0, $length);
                break;
            default :
                $i = 0;
                $r = "";
                while($i ++ < $length) {
                    $r .= chr(mt_rand(0, 255));
                }
                break;
        }
        return substr(bin2hex($r), 0, $length);
    }
}

फ़ायरफ़ॉक्स और क्रोम में परीक्षण

यहां छवि विवरण दर्ज करें

फायदा

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

हानि

  • कई ब्राउज़र (मोबाइल और वेब) के माध्यम से लगातार कनेक्शन का समर्थन नहीं करता
  • कुकी अभी भी चुराई जा सकती है क्योंकि उपयोगकर्ता को केवल अगले लॉगिन के बाद सूचना मिलती है।

जल्दी ठीक

  • प्रत्येक सिस्टम के लिए अनुमोदन प्रणाली का परिचय, जिसमें निरंतर कनेक्शन होना चाहिए
  • प्रमाणीकरण के लिए कई कुकीज़ का उपयोग करें

मल्टीपल कुकी दृष्टिकोण

जब एक हमलावर कुकीज़ चुराने वाला होता है तो वह केवल किसी विशेष वेबसाइट या डोमेन उदा पर ध्यान केंद्रित करता है। example.com

लेकिन वास्तव में आप (2 अलग डोमेन से एक उपयोगकर्ता को प्रमाणित कर सकते हैं example.com और fakeaddsite.com ) है और यह "विज्ञापन कुकी" की तरह लग रहे बनाने के

  • उपयोगकर्ता मुझे याद करने के लिए example.com पर लॉग ऑन हुआ
  • स्टोर उपयोगकर्ता नाम, टोकन, कुकी में संदर्भ
  • स्टोर यूजरनेम, टोकन, डेटाबेस में संदर्भ उदा। मेम्कैश
  • रेफरी आईडी भेजें और iframe के माध्यम से fakeaddsite.com पर भेजें
  • fakeaddsite.com डेटाबेस से उपयोगकर्ता और टोकन लाने के लिए संदर्भ का उपयोग करता है
  • fakeaddsite.com हस्ताक्षर संग्रहीत करता है
  • जब कोई उपयोगकर्ता fakeaddsite.com से iframe के साथ हस्ताक्षर हस्ताक्षर जानकारी लौटा रहा है
  • इसे डेटा को संयोजित करें और सत्यापन करें
  • ..... आप शेष जानते हैं

कुछ लोगों को आश्चर्य हो सकता है कि आप 2 अलग-अलग कुकीज़ का उपयोग कैसे कर सकते हैं? वैसे इसकी संभव, कल्पना example.com = localhostऔर fakeaddsite.com = 192.168.1.120। यदि आप कुकीज़ का निरीक्षण करते हैं तो यह इस तरह दिखेगा

यहां छवि विवरण दर्ज करें

ऊपर की छवि से

  • वर्तमान साइट का दौरा किया गया है लोकलहोस्ट
  • इसमें 192.168.1.120 से सेट कुकीज़ भी शामिल हैं

192.168.1.120

  • केवल परिभाषित स्वीकार करता है HTTP_REFERER
  • केवल निर्दिष्ट से कनेक्शन स्वीकार करता है REMOTE_ADDR
  • कोई जावास्क्रिप्ट नहीं, कोई सामग्री नहीं है, लेकिन साइन जानकारी के बजाय कुछ भी नहीं है और इसे कुकी से जोड़ें या पुनर्प्राप्त करें

फायदा

  • 99% प्रतिशत समय आपने हमलावर को धोखा दिया है
  • आप हमलावर के पहले प्रयास में आसानी से खाता लॉक कर सकते हैं
  • अन्य तरीकों की तरह अगले लॉगिन से पहले भी हमले को रोका जा सकता है

हानि

  • केवल एक लॉगिन के लिए सर्वर से एकाधिक अनुरोध

सुधार की

  • हो गया उपयोग iframe का उपयोग करें ajax

5
भले ही @ircmaxell ने सिद्धांत का अच्छी तरह से वर्णन किया है, मैं इस दृष्टिकोण को पसंद करता हूं, क्योंकि यह उपयोगकर्ता आईडी को स्टोर करने की आवश्यकता के बिना उत्कृष्ट काम करता है (जो एक अवांछित प्रकटीकरण होगा) और इसमें केवल उपयोगकर्ता आईडी और हैश की तुलना में अधिक फिंगरप्रिंट भी शामिल हैं। उपयोगकर्ता, जैसे कि ब्राउज़र। यह एक हमलावर के लिए चोरी कुकी का उपयोग करना और भी कठिन बना देता है। यह अब तक का सबसे अच्छा और सबसे सुरक्षित तरीका है। +1
मार्सेलो मोन्केमेयर

6

मैंने इस प्रश्न का एक कोण यहां पूछा है , और उत्तर आपको सभी टोकन-आधारित टाइम-आउट कुकी लिंक की आवश्यकता होगी।

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


6

पुराना धागा, लेकिन अभी भी एक वैध चिंता का विषय है। मैंने सुरक्षा के बारे में कुछ अच्छी प्रतिक्रियाओं पर ध्यान दिया, और 'अस्पष्टता के माध्यम से सुरक्षा' के उपयोग से बचा, लेकिन दी गई वास्तविक तकनीकी विधियाँ मेरी दृष्टि में पर्याप्त नहीं थीं। इससे पहले कि मैं अपनी पद्धति में योगदान करूँ, मुझे जो बातें कहनी चाहिए:

  • कभी भी स्पष्ट पाठ में पासवर्ड न रखें ... कभी!
  • कभी नहीँअपने डेटाबेस में एक से अधिक स्थानों पर उपयोगकर्ता के हैशेड पासवर्ड को । आपका सर्वर बैकएंड हमेशा उपयोगकर्ता तालिका से हैशेड पासवर्ड खींचने में सक्षम है। अतिरिक्त डीबी लेनदेन के बदले अनावश्यक डेटा को स्टोर करना अधिक कुशल नहीं है, उलटा सच है।
  • आपकी सत्र आईडी अद्वितीय होनी चाहिए, इसलिए कोई भी दो उपयोगकर्ता कभी भी एक आईडी साझा नहीं कर सकते हैं , इसलिए एक आईडी का उद्देश्य (क्या आपके ड्राइवर का लाइसेंस आईडी नंबर कभी अन्य व्यक्तियों से मेल कर सकता है? नहीं) यह 2 के आधार पर एक दो-टुकड़ा अद्वितीय संयोजन बनाता है? अद्वितीय तार। आपके सत्र तालिका को PK के रूप में ID का उपयोग करना चाहिए। ऑटो-साइनिन के लिए कई उपकरणों पर भरोसा करने की अनुमति देने के लिए, भरोसेमंद उपकरणों के लिए एक और तालिका का उपयोग करें जिसमें सभी मान्य उपकरणों की सूची शामिल है (नीचे मेरा उदाहरण देखें), और उपयोगकर्ता नाम का उपयोग करके मैप किया गया है।
  • यह कुकी में ज्ञात डेटा को हैश करने का कोई उद्देश्य नहीं रखता है, कुकी की प्रतिलिपि बनाई जा सकती है। हम जिस चीज की तलाश कर रहे हैं वह एक प्रामाणिक उपयोगकर्ता उपकरण है जो प्रामाणिक जानकारी प्रदान करने के लिए है जो उपयोगकर्ता की मशीन से समझौता किए बिना किसी हमलावर को प्राप्त नहीं कर सकता है (फिर से, मेरा उदाहरण देखें)। हालांकि, इसका मतलब यह होगा कि एक वैध उपयोगकर्ता जो अपनी मशीन की स्थिर जानकारी (यानी मैक पता, डिवाइस होस्टनाम, यदि ब्राउज़र आदि द्वारा प्रतिबंधित है, तो उपयोगकर्ता से मना करता है) को शेष सुसंगत (या इसे पहले स्थान पर खराब कर) नहीं कर पाएगा। इस सुविधा का उपयोग करें। लेकिन अगर यह चिंता का विषय है, तो इस तथ्य पर विचार करें कि आप उपयोगकर्ताओं को ऑटो-साइनइन की पेशकश कर रहे हैं अपनी विशिष्ट पहचान रखते हैं, इसलिए यदि वे अपने मैक को खराब करने, अपने उपयोगकर्ता को खराब करने, स्पूफिंग को बदलने / अपने होस्टनाम को बदलने, परदे के पीछे छिपने, आदि के बारे में जानने से इनकार करते हैं, तो वे पहचानने योग्य नहीं हैं, और कभी भी स्वचालित सेवा के लिए प्रमाणित नहीं होना चाहिए। यदि आप यह चाहते हैं, तो आपको क्लाइंट-साइड सॉफ़्टवेयर के साथ बंडल किए गए स्मार्ट-कार्ड एक्सेस पर ध्यान देने की आवश्यकता है जो डिवाइस के उपयोग के लिए पहचान स्थापित करता है।

कहा जा रहा है कि आपके सिस्टम पर ऑटो-साइनइन करने के दो शानदार तरीके हैं।

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

यह सस्ता है, और कुछ लोगों द्वारा इसे गंदा भी माना जा सकता है, क्योंकि यह आपके संभावित रूप से पहले से ही Google और फेसबुक जैसी जगहों पर स्वयं को बिना बताए मान्य करने का प्रयास करता है। हालांकि, इसका उपयोग उन उपयोगकर्ताओं पर नहीं किया जाना चाहिए जिन्होंने आपकी साइट पर ऑटो-साइनइन करने के लिए नहीं कहा है, और यह विशेष विधि केवल बाहरी प्रमाणीकरण के लिए है, जैसे कि Google+ या एफबी।

क्योंकि एक बाहरी प्रमाणीकरणकर्ता का उपयोग पर्दे के पीछे सर्वर को यह बताने के लिए किया जाता था कि उपयोगकर्ता को मान्य किया गया था या नहीं, एक हमलावर एक अद्वितीय आईडी के अलावा कुछ भी प्राप्त नहीं कर सकता है, जो अपने आप में बेकार है। मैं विस्तृत हूँ:

  • उपयोगकर्ता 'जो' पहली बार साइट पर जाता है, कुकी आईडी 'सत्र' में रखा गया है।
  • उपयोगकर्ता 'जो' लॉग इन करता है, विशेषाधिकार बढ़ाता है, नई सत्र आईडी प्राप्त करता है और कुकी 'सत्र' को नवीनीकृत करता है।
  • उपयोगकर्ता 'जो' google + का उपयोग करके ऑटो-साइनिन के लिए चुनाव करता है, उसे कुकी 'Keepmesignin' में रखी गई एक विशिष्ट आईडी मिलती है।
  • उपयोगकर्ता 'जो' में Google ने उन्हें साइन इन किया है, जिससे आपकी साइट आपके बैकएंड में Google का उपयोग करने वाले उपयोगकर्ता को ऑटो-साइनइन कर सकती है।
  • हमलावर 'रख-रखाव' के लिए यूनिक आईडी की व्यवस्थित रूप से कोशिश करता है (यह हर उपयोगकर्ता को दिया गया सार्वजनिक ज्ञान है), और कहीं और हस्ताक्षरित नहीं है; 'joe' को दी गई अद्वितीय ID की कोशिश करता है।
  • सर्वर को 'जो' के लिए यूनिक आईडी मिलती है, जो google + अकाउंट के लिए DB में मैच खींचती है।
  • सर्वर हमलावर को लॉगिन पेज पर भेजता है जो लॉगिन करने के लिए google को AJAX अनुरोध करता है।
  • Google सर्वर अनुरोध प्राप्त करता है, हमलावर को देखने के लिए उसके एपीआई का उपयोग करता है, वर्तमान में लॉग इन नहीं है।
  • Google प्रतिक्रिया भेजता है कि वर्तमान में इस कनेक्शन पर उपयोगकर्ता में कोई हस्ताक्षर नहीं है।
  • हमलावर के पेज को प्रतिक्रिया मिलती है, स्क्रिप्ट स्वचालित रूप से url में एन्कोड किए गए POST मान के साथ लॉगिन पृष्ठ पर रीडायरेक्ट करती है।
  • लॉगिन पेज से POST का मूल्य मिलता है, स्वचालित मान रखने के लिए 1-1-1970 की तारीख तक एक खाली मूल्य और 'मान्य' के लिए कुकी भेजता है, स्वचालित रूप से कुकी को हटाने के लिए हमलावर का ब्राउज़र।
  • हमलावर को सामान्य पहली बार लॉगिन पृष्ठ दिया गया है।

कोई फर्क नहीं पड़ता है, भले ही एक हमलावर एक आईडी का उपयोग करता है जो मौजूद नहीं है, प्रयास को सभी प्रयासों पर विफल होना चाहिए सिवाय एक मान्य प्रतिक्रिया प्राप्त होने पर।

यह विधि उन लोगों के लिए आपके आंतरिक प्रमाणक के साथ संयोजन के रूप में इस्तेमाल की जा सकती है और होनी चाहिए जो बाहरी प्रमाणक का उपयोग करके आपकी साइट पर हस्ताक्षर करते हैं।

=========

अब, अपने स्वयं के प्रमाणक सिस्टम के लिए जो उपयोगकर्ताओं को ऑटो-साइनइन कर सकता है, यह है कि मैं यह कैसे करता हूं:

DB में कुछ सारणी हैं:

TABLE users:
UID - auto increment, PK
username - varchar(255), unique, indexed, NOT NULL
password_hash - varchar(255), NOT NULL
...

ध्यान दें कि उपयोगकर्ता नाम 255 वर्ण लंबा होने में सक्षम है। मेरे पास मेरे सिस्टम प्रोग्राम में उपयोगकर्ता नाम 32 अक्षरों तक सीमित है, लेकिन बाहरी प्रमाण-पत्र के उपयोगकर्ता नाम उनके @ domain.tld से बड़े हो सकते हैं, इसलिए मैं अधिकतम संगतता के लिए ईमेल पते की अधिकतम लंबाई का समर्थन करता हूं।

TABLE sessions:
session_id - varchar(?), PK
session_token - varchar(?), NOT NULL
session_data - MediumText, NOT NULL

ध्यान दें कि इस तालिका में कोई उपयोगकर्ता फ़ील्ड नहीं है, क्योंकि उपयोगकर्ता नाम, जब लॉग इन किया जाता है, सत्र डेटा में होता है, और प्रोग्राम शून्य डेटा की अनुमति नहीं देता है। Session_id और session_token यादृच्छिक md5 हैश, sha1 / 128/256 हैश का उपयोग करके उत्पन्न किया जा सकता है, यादृच्छिक स्ट्रिंग्स के साथ डेटाटाइम स्टैम्प्स उन्हें जोड़ा गया है, या जो भी आप चाहें, लेकिन आपके आउटपुट का एन्ट्रापी उतना ही सहन करने योग्य होना चाहिए मूक-बधिर बल के हमलों को जमीन से दूर होने से भी कम करें, और आपके सत्र वर्ग द्वारा उत्पन्न सभी हैश को उन्हें जोड़ने के प्रयास से पहले सत्र तालिका में मैचों के लिए जाँच की जानी चाहिए।

TABLE autologin:
UID - auto increment, PK
username - varchar(255), NOT NULL, allow duplicates
hostname - varchar(255), NOT NULL, allow duplicates
mac_address - char(23), NOT NULL, unique
token - varchar(?), NOT NULL, allow duplicates
expires - datetime code

उनके स्वभाव से मैक पते को अद्वितीय माना जाता है, इसलिए यह समझ में आता है कि प्रत्येक प्रविष्टि का एक अद्वितीय मूल्य है। दूसरी ओर, होस्टनाम को अलग-अलग नेटवर्क पर वैध तरीके से दोहराया जा सकता है। कितने लोग "होम-पीसी" का उपयोग अपने कंप्यूटर नामों में से एक के रूप में करते हैं? उपयोगकर्ता नाम बैकएंड द्वारा सत्र डेटा से लिया जाता है, इसलिए इसे हेरफेर करना असंभव है। टोकन के लिए, उपयोगकर्ता ऑटो-साइनिन के लिए कुकीज़ में टोकन उत्पन्न करने के लिए पृष्ठों के लिए सत्र टोकन उत्पन्न करने के लिए एक ही विधि का उपयोग किया जाना चाहिए। अंत में, जब उपयोगकर्ता को अपने क्रेडेंशियल्स को पुन: अमान्य करने की आवश्यकता होगी, तो डेटाटाइम कोड जोड़ा जाता है। या तो इस डेटाटाइम को कुछ दिनों के भीतर रखने वाले उपयोगकर्ता लॉगिन पर अपडेट करें, या इसे अंतिम लॉगिन की परवाह किए बिना समाप्त करने के लिए मजबूर करें, इसे केवल एक या एक महीने के लिए रखें, जो भी आपके डिज़ाइन को निर्धारित करता है।

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

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

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

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

अगर किसी को मेरे जवाब में कोड दिए जाने की उम्मीद थी, तो मैं माफी मांगता हूं, यहां ऐसा नहीं होने जा रहा है। मैं कहूंगा कि मैं अपनी साइटों को चलाने के लिए PHP, jQuery और AJAX का उपयोग करता हूं, और मैं कभी भी सर्वर के रूप में विंडोज का उपयोग नहीं करता ...


5

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


4

एक हैश उत्पन्न करें, हो सकता है कि केवल एक रहस्य जिसे आप जानते हैं, फिर उसे अपने DB में संग्रहीत करें ताकि वह उपयोगकर्ता के साथ संबद्ध हो सके। काफी अच्छा काम करना चाहिए।


क्या यह एक विशिष्ट पहचानकर्ता होगा जो उपयोगकर्ता द्वारा बनाए जाने पर बनाया जाता है, या हर बार जब उपयोगकर्ता एक नया "कीप मी लॉग इन" कुकी बनाता है, तो क्या यह बदल जाएगा?
मैथ्यू

1
टिम जानसन का जवाब हैश के उत्पादन के लिए एक अच्छा दृष्टिकोण का वर्णन करता है, हालांकि मुझे यह सुरक्षित महसूस होता है अगर इसमें पासवर्ड शामिल नहीं है
जानी हार्टिकेनन

2

मेरा समाधान इस तरह है। यह 100% बुलेटप्रूफ नहीं है, लेकिन मुझे लगता है कि यह आपको अधिकांश मामलों के लिए बचाएगा।

जब उपयोगकर्ता लॉग इन सफलतापूर्वक इस जानकारी के साथ एक स्ट्रिंग बनाएँ:

$data = (SALT + ":" + hash(User Agent) + ":" + username 
                     + ":" + LoginTimestamp + ":"+ SALT)

एन्क्रिप्ट करें $data, HttpOnly पर टाइप करें और कुकी सेट करें।

जब उपयोगकर्ता आपकी साइट पर वापस आता है, तो यह चरण बनाएं:

  1. कुकी डेटा प्राप्त करें। कुकी के अंदर के खतरनाक पात्रों को निकालें। इसके साथ विस्फोट करें: चरित्र के ।
  2. वैधता की जाँच करें। अगर कुकी X दिनों से पुरानी है, तो उपयोगकर्ता को लॉगिन पृष्ठ पर पुनर्निर्देशित करें।
  3. यदि कुकी पुरानी नहीं है; डेटाबेस से नवीनतम पासवर्ड परिवर्तन समय प्राप्त करें। यदि उपयोगकर्ता के अंतिम लॉगिन रीडायरेक्ट के बाद पासवर्ड को लॉगिन पेज पर बदल दिया जाता है।
  4. यदि हाल ही में पास नहीं बदला गया था; उपयोगकर्ता के वर्तमान ब्राउज़र एजेंट प्राप्त करें। जांचें कि क्या (currentUserAgentHash == cookieUserAgentHash)। यदि एजेंट अगले चरण में जाते हैं, तो लॉगिन पृष्ठ पर पुनः निर्देशित करें।
  5. यदि सभी चरण सफलतापूर्वक पारित हो गए तो उपयोगकर्ता नाम अधिकृत करें।

यदि उपयोगकर्ता हस्ताक्षर करते हैं, तो इस कुकी को हटा दें। यदि उपयोगकर्ता फिर से लॉगिन करता है तो नया कुकी बनाएँ।


2

मुझे कुकी में एन्क्रिप्ट किए गए सामान को संग्रहीत करने की अवधारणा समझ में नहीं आती है जब यह इसका एन्क्रिप्टेड संस्करण है जिसे आपको अपनी हैकिंग करने की आवश्यकता है। अगर मुझे कुछ याद आ रहा है, तो कृपया टिप्पणी करें।

मैं to रिमेंबर मी ’के लिए यह तरीका अपनाने के बारे में सोच रहा हूं। यदि आप किसी भी मुद्दे को देख सकते हैं, तो कृपया टिप्पणी करें।

  1. "मुझे याद रखें" डेटा को स्टोर करने के लिए एक तालिका बनाएं - उपयोगकर्ता तालिका में अलग करें ताकि मैं कई उपकरणों से लॉग इन कर सकूं।

  2. सफल लॉगिन पर (याद रखें मेरे साथ टिकटिक):

    a) इस मशीन पर UserID के रूप में उपयोग किए जाने के लिए एक अद्वितीय यादृच्छिक स्ट्रिंग उत्पन्न करें: bigUserID

    बी) एक अद्वितीय यादृच्छिक स्ट्रिंग उत्पन्न करें: bigKey

    c) कुकी को स्टोर करें: bigUserID: bigKey

    d) "रिमेम्बर मी" टेबल में, एक रिकॉर्ड जोड़ें: UserID, IP एड्रेस, bigUserID, bigKey

  3. यदि लॉगिन के लिए किसी ऐसी चीज़ का उपयोग करने की कोशिश की जा रही है:

    क) कुकी के लिए जाँच करें और एक मिलान आईपी पते के साथ bigUserID और bigKey के लिए खोजें

    ख) यदि आपको यह पता है, तो उस व्यक्ति को लॉग इन करें, लेकिन उपयोगकर्ता तालिका "सॉफ्ट लॉगिन" में एक झंडा सेट करें ताकि किसी भी खतरनाक ऑपरेशन के लिए, आप पूर्ण लॉगिन के लिए संकेत दे सकें।

  4. लॉगआउट होने पर, उस उपयोगकर्ता के सभी "याद रखें" रिकॉर्ड की समय सीमा समाप्त हो गई है।

केवल कमजोरियाँ जो मैं देख सकता हूँ;

  • आप किसी के लैपटॉप को पकड़ सकते हैं और कुकी के साथ उनका आईपी पता खराब कर सकते हैं।
  • आप हर बार एक अलग आईपी पते को बिगाड़ सकते हैं और पूरी बात का अनुमान लगा सकते हैं - लेकिन दो बड़े स्ट्रिंग के साथ मिलान करने के लिए, यह होगा ... ऊपर एक समान गणना कर रहा है ... मुझे कोई पता नहीं है ... भारी अंतर?

नमस्कार, और इस उत्तर के लिए धन्यवाद, मुझे यह पसंद है। एक सवाल हालांकि: आपको 2 यादृच्छिक स्ट्रिंग्स क्यों उत्पन्न करने होंगे - bigUserID & bigKey? आप केवल 1 को क्यों उत्पन्न नहीं करते हैं और इसका उपयोग नहीं करते हैं?
जेरेमी बेलोलो

2
BigKey समय की पूर्वनिर्धारित राशि के बाद समाप्त हो जाती है, लेकिन bigUserID नहीं करता है। bigUserID आपको एक ही IP पते पर विभिन्न उपकरणों पर कई सत्रों की अनुमति देता है। आशा है कि समझ में आता है - मुझे एक पल के लिए सोचना पड़ा :)
Enigma Plus

Hmac में एक चीज मदद कर सकती है, यदि आपको hmac छेड़छाड़ मिली, तो आप निश्चित रूप से जान सकते हैं कि किसी ने कुकी चुराने की कोशिश की, तो आप हर लॉगिन स्थिति को रीसेट कर सकते हैं। क्या मैं सही हू?
सूरज जैन

2

मैंने सभी उत्तर पढ़े और फिर भी मुझे जो करना चाहिए था उसे निकालना मुश्किल हो गया। यदि कोई चित्र 1k शब्दों के लायक है, तो मुझे आशा है कि यह बैरी जैसपन के बेहतर लगातार लॉगिन कुकी सर्वोत्तम अभ्यास के आधार पर दूसरों को एक सुरक्षित निरंतर भंडारण को लागू करने में मदद करता है।

यहां छवि विवरण दर्ज करें

यदि आपके पास प्रश्न, प्रतिक्रिया या सुझाव हैं, तो मैं एक सुरक्षित लगातार लॉगिन को लागू करने की कोशिश कर रहे नौसिखियों के लिए चित्र को अपडेट करने के लिए आरेख को अपडेट करने का प्रयास करूंगा।


0

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

मैं आपको पूछ सकता हूँ "2 दिन क्यों? 2 सप्ताह क्यों नहीं?"। ऐसा इसलिए है क्योंकि PHP में एक सत्र का उपयोग करने से स्वचालित रूप से समाप्ति की तारीख वापस आ जाएगी। ऐसा इसलिए है क्योंकि PHP में एक सत्र की समाप्ति वास्तव में एक निष्क्रिय समय समाप्ति है।

अब, कहा जा रहा है कि, मैं शायद एक कठिन टाइमआउट मान लागू करूंगा, जिसे मैं सत्र में ही स्टोर करता हूं, और 2 सप्ताह या उससे अधिक समय तक, और यह देखने के लिए और सत्र को जबरन अमान्य करने के लिए कोड जोड़ें। या कम से कम उन्हें लॉग आउट करने के लिए। इसका मतलब यह होगा कि उपयोगकर्ता को समय-समय पर लॉगिन करने के लिए कहा जाएगा। याहू! क्या ये।


1
एक लंबा सत्र सेट करना संभवतः खराब है क्योंकि यह सर्वर संसाधनों को बर्बाद करता है और यह प्रदर्शन को प्रतिकूल रूप से प्रभावित करेगा
user3091530

0

मुझे लगता है कि आप ऐसा कर सकते हैं:

$cookieString = password_hash($username, PASSWORD_DEFAULT);

$cookiestringDB में स्टोर करें और कुकी के रूप में सेट करें। व्यक्ति के उपयोगकर्ता नाम को कुकी के रूप में भी सेट करें। एक हैश की पूरी बात यह है कि इसे रिवर्स-इंजीनियर नहीं किया जा सकता है।

जब कोई उपयोगकर्ता चालू होता है, तो $cookieStringकिसी अन्य की तुलना में एक कुकी से उपयोगकर्ता नाम प्राप्त करें । यदि $cookieStringDB में संग्रहीत एक से मेल खाता है, तो उपयोगकर्ता प्रमाणित है। चूंकि पासवर्ड_शश हर बार एक अलग नमक का उपयोग करता है, इसलिए यह अप्रासंगिक है कि स्पष्ट पाठ क्या है।

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