복붙노트

"Keep Me Logged In"- 최선의 접근 방식

PHP

"Keep Me Logged In"- 최선의 접근 방식

내 웹 응용 프로그램은 세션을 사용하여 로그인 한 사용자에 대한 정보를 저장하고 응용 프로그램 내에서 페이지간에 이동할 때 해당 정보를 유지 관리합니다. 이 특정 애플리케이션에서는 person_id, first_name 및 last_name을 저장합니다.

나는 사용자의 컴퓨터에 2 주 동안 쿠키를 저장하는 로그인에 "로그인 한 상태로 유지"옵션을 제공하고 싶습니다. 그러면 앱으로 돌아갈 때 동일한 세부 정보로 세션이 다시 시작됩니다.

이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 한 사용자가 다른 사용자의 신원을 쉽게 확인하고 위조 할 수 있도록 쿠키에 user_id를 저장하고 싶지 않습니다.

해결법

  1. ==============================

    1.좋아,이 말을 솔직하게 말하자. 사용자 데이터 나 사용자 데이터에서 파생 된 것을 쿠키에 넣어 두는 경우 잘못된 작업을 수행하는 것입니다.

    좋아,이 말을 솔직하게 말하자. 사용자 데이터 나 사용자 데이터에서 파생 된 것을 쿠키에 넣어 두는 경우 잘못된 작업을 수행하는 것입니다.

    그곳에. 내가 말했어. 이제 실제 답변으로 이동할 수 있습니다.

    사용자 데이터를 해싱하는 것이 잘못된 이유는 무엇입니까? 음, 그것은 노출 표면과 무명을 통해 보안에 온다.

    당신이 공격자라고 잠시 상상해보십시오. 세션에서 remember-me에 대한 암호화 쿠키 세트가 표시됩니다. 너비는 32 자입니다. 말. MD5일지도 ..

    잠깐 동안 그들이 사용했던 알고리즘을 알고 있다고 상상해보십시오. 예 :

    md5(salt+username+ip+salt)
    

    이제 공격자는 "소금"(실제로 소금이 아니지만 나중에는 더 많은 것)을 무차별 적으로 공격해야합니다. 이제 그는 자신의 IP 주소로 모든 사용자 이름으로 원하는 모든 가짜 토큰을 생성 할 수 있습니다! 그러나 소금을 강압적으로 사용하는 것은 어렵습니다. 전혀. 그러나 현대 GPU는 매우 훌륭합니다. 그리고 충분히 무작위로 사용하지 않으면 (충분히 크게 만들어야합니다.), 빨리 성의가 떨어질 것입니다.

    요컨대, 당신을 보호하는 유일한 방법은 당신이 생각하는만큼 당신을 보호하지 않는 소금입니다.

    하지만 기다려!

    이 모든 것은 침입자가 알고리즘을 알고 있다고 단언했습니다! 비밀스럽고 혼란 스럽다면 안전합니다. 맞죠? 잘못된. 그 사고 방식에는 이름이 있습니다 : 보안을 통한 보안. 절대 신뢰해서는 안됩니다.

    더 나은 길

    더 좋은 방법은 ID를 제외하고 사용자 정보가 서버를 떠나지 않도록하는 것입니다.

    사용자가 로그인하면 큰 (128 ~ 256 비트) 임의 토큰을 생성합니다. 토큰을 userid에 매핑하는 데이터베이스 테이블에 추가 한 다음이를 쿠키의 클라이언트로 보냅니다.

    공격자가 다른 사용자의 임의의 토큰을 추측하면 어떻게됩니까?

    여기서 수학을 해보 죠. 128 비트 랜덤 토큰을 생성 중입니다. 즉, 다음과 같은 것을 의미합니다.

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

    이제 그 숫자가 얼마나 터무니 없는지를 보여주기 위해 인터넷에있는 모든 서버를 상상해 봅시다. (현재 5 천만 개라고 가정 해 봅시다) 초당 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 섹트 초 ...

    그걸 더 친숙한 번호로 가져 가려고 노력합시다.

    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 또는 DEV_URANDOM과 함께 mcrypt_create_iv () 라이브러리를 사용하십시오 ...

    hash_equals ()는 타이밍 공격을 방지하기위한 것입니다. PHP 5.6 미만의 PHP 버전을 사용하는 경우 hash_equals () 함수는 지원되지 않습니다. 이 경우 hashSequals ()를 timingSafeCompare 함수로 바꿀 수 있습니다.

    /**
     * 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;
    }
    
  2. ==============================

    2.보통 나는 이렇게한다.

    보통 나는 이렇게한다.

    물론 다른 쿠키 이름 등을 사용할 수도 있습니다. 쿠키의 내용을 조금 변경할 수도 있습니다. 쉽게 만들 수 없는지 확인하십시오. 예를 들어 사용자가 생성 될 때 user_salt를 생성하고이를 쿠키에 넣을 수도 있습니다.

    또한 md5 (또는 거의 모든 알고리즘) 대신 sha1을 사용할 수 있습니다.

  3. ==============================

    3.소개

    소개

    제목 "Keep Me Logged In"- 가장 좋은 방법은 다음과 같은 사항을 고려해야하기 때문에 최상의 접근 방법을 찾고 있기 때문에 어디에서 시작해야하는지 알기가 어렵습니다.

    쿠키

    쿠키는 취약합니다. 일반적인 브라우저 쿠키 도용 취약점과 크로스 사이트 스크립팅 공격 사이에서 우리는 쿠키가 안전하지 않다는 사실을 인정해야합니다. 보안을 강화하려면 php setcookies에는 다음과 같은 추가 기능이 있습니다.

    정의

    간단한 접근법

    간단한 해결책은 다음과 같습니다.

    위의 사례 연구는이 페이지에 제시된 모든 예를 요약했지만 단점은

    더 나은 솔루션

    더 나은 해결책은

    예제 코드

    // 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);
        }
    }
    

    Firefox 및 Chrome 테스트

    이점

    불리

    빠른 수정

    다중 쿠키 접근법

    공격자가 요리를 훔치려 고 할 때 특정 웹 사이트 또는 도메인에만 초점을 맞 춥니 다. example.com

    하지만 실제로는 2 개의 다른 도메인 (example.com 및 fakeaddsite.com)에서 사용자를 인증하고 "쿠키 쿠키"와 같이 보이게 할 수 있습니다.

    어떤 사람들은 2 가지 쿠키를 어떻게 사용할 수 있을지 궁금해 할 것입니다. 가능한 한, example.com = localhost 및 fakeaddsite.com = 192.168.1.120을 상상해보십시오. 쿠키를 검사하면 다음과 같이 보일 것입니다.

    위 이미지에서

    192.168.1.120

    이점

    불리

    개량

  4. ==============================

    4.두 가지 매우 흥미로운 기사가 ​​있는데, "기억 나"문제에 대한 완벽한 해결책을 찾고있는 동안 발견했습니다.

    두 가지 매우 흥미로운 기사가 ​​있는데, "기억 나"문제에 대한 완벽한 해결책을 찾고있는 동안 발견했습니다.

  5. ==============================

    5.나는이 질문에 대해 하나의 질문을 던졌고 답은 당신이 필요로하는 모든 토큰 기반 타이밍 아웃 쿠키 링크로 안내 할 것이다.

    나는이 질문에 대해 하나의 질문을 던졌고 답은 당신이 필요로하는 모든 토큰 기반 타이밍 아웃 쿠키 링크로 안내 할 것이다.

    기본적으로 userId는 쿠키에 저장하지 않습니다. 사용자가 이전 로그인 세션을 선택하는 데 사용하는 일회성 토큰 (거대한 문자열)을 저장합니다. 그런 다음 보안을 강화하려면 무거운 작업 (예 : 암호 자체 변경)에 대한 암호를 요청하십시오.

  6. ==============================

    6.Stefan에서 언급 한 접근 방식을 권장합니다 (즉, 향상된 영구 로그인 쿠키 모범 사례의 지침을 따르십시오). 또한 쿠키가 HttpOnly 쿠키인지 확인하여 잠재적으로 악의적 인 JavaScript에 액세스 할 수 없도록하는 것이 좋습니다.

    Stefan에서 언급 한 접근 방식을 권장합니다 (즉, 향상된 영구 로그인 쿠키 모범 사례의 지침을 따르십시오). 또한 쿠키가 HttpOnly 쿠키인지 확인하여 잠재적으로 악의적 인 JavaScript에 액세스 할 수 없도록하는 것이 좋습니다.

  7. ==============================

    7.해시를 생성하십시오. 아마도 비밀로만 알고, DB에 저장하여 사용자와 연관시킬 수 있습니다. 꽤 잘해야합니다.

    해시를 생성하십시오. 아마도 비밀로만 알고, DB에 저장하여 사용자와 연관시킬 수 있습니다. 꽤 잘해야합니다.

  8. ==============================

    8.오래된 스레드,하지만 여전히 유효한 우려. 나는 보안에 대한 좋은 반응을 보았고 '모호함을 통한 보안'사용을 피했지만 실제로 주어진 기술적 방법으로는 충분하지 않았습니다. 내 방법을 제공하기 전에 내가 반드시 말해야 할 사항 :

    오래된 스레드,하지만 여전히 유효한 우려. 나는 보안에 대한 좋은 반응을 보았고 '모호함을 통한 보안'사용을 피했지만 실제로 주어진 기술적 방법으로는 충분하지 않았습니다. 내 방법을 제공하기 전에 내가 반드시 말해야 할 사항 :

    즉, 시스템에 자동 로그인을 사용하는 두 가지 좋은 방법이 있습니다.

    첫째, 저렴하고 쉬운 방법으로 모든 것을 다른 사람에게 맡깁니다. 예를 들어, Google + 계정으로 사이트 지원을 로그인하면 Google에 이미 로그인되어있는 경우 사용자를 로그인하는 간소화 된 google + 버튼이있을 것입니다 (나는 항상이 질문에 대답했습니다. Google에 로그인). 사용자가 신뢰할 수 있고 지원되는 인증 자로 이미 로그인 한 상태에서 사용자가 자동으로 로그인하고 확인란을 선택하면 클라이언트 측 스크립트가로드하기 전에 해당 '로그인 버튼'뒤에 코드를 수행하게하십시오 , 서버에 사용자 이름, 세션 ID 및 사용자에게 사용되는 인증자를 가진 자동 서명 테이블에 고유 ID를 저장하도록하십시오. 이러한 로그인 방법은 AJAX를 사용하기 때문에 어쨌든 응답을 기다리고 있으며 그 응답은 검증 된 응답이거나 거부입니다. 유효성을 확인한 응답이 있으면 정상적으로 응답 한 다음 정상적으로 로그인 한 사용자를 계속로드하십시오. 그렇지 않으면 로그인에 실패했지만 사용자에게 알리지 않고 로그인하지 않은 상태로 계속하면 알 수 있습니다. 이것은 쿠키를 훔친 공격자가 사용자가 사이트에 자동으로 로그인 한 것을 알지 못하도록 (또는 권한을 상승시키기 위해 위조 한) 공격자를 방지하기위한 것입니다.

    이것은 싸고, 심지어 당신에게 말하기조차하지 않고, 구글이나 페이스 북과 같은 장소로 잠재적으로 이미 서명 된 자신을 확인하려고 시도하기 때문에 어떤 사람들에게는 더러워진 것으로 간주 될 수도 있습니다. 그러나 자동 로그인을 요청하지 않은 사용자는 Google+ 또는 FB와 같은 외부 인증에만 사용해야합니다.

    사용자가 유효한지 여부에 관계없이 외부 인증자가 서버 뒤에서 서버를 알리기 때문에 공격자는 고유 한 ID 이외의 것을 얻을 수 없으며 그 자체로는 쓸모가 없습니다. 나는 정교하게 다룰 것이다 :

    무엇을 상관없이 공격자가 존재하지 않는 ID를 사용하더라도 유효한 응답을받을 때를 제외하고 모든 시도에서 시도가 실패해야합니다.

    이 방법은 외부 인증자를 사용하여 사이트에 로그인하는 사람들을 위해 내부 인증 자와 함께 사용할 수도 있고 사용해야 할 수도 있습니다.

    =========

    이제는 사용자가 자동으로 로그인 할 수있는 독자적인 인증 시스템을 사용하는 방법입니다.

    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
    

    로그인 할 때 사용자 이름이 세션 데이터에 있고 프로그램이 널 (null) 데이터를 허용하지 않으므로이 테이블에 사용자 필드가 없음을 유의하십시오. session_id와 session_token은 무작위 md5 해시, sha1 / 128 / 256 해시, 무작위 문자열을 추가 한 datetime 스탬프, 해시 등 원하는 것을 사용하여 생성 할 수 있지만 출력의 엔트로피는 다음과 같이 높은 수준으로 유지되어야합니다. 지상에서 내려 오는 경우에도 무차별 대입 공격을 완화하고 세션 클래스에서 생성 된 모든 해시는 세션 테이블에서 일치 항목을 확인한 후에 추가해야합니다.

    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
    

    MAC 주소는 그 특성에 따라 UNIQUE로 간주되므로 각 항목마다 고유 한 값이 있습니다. 반면 호스트 이름은 합법적 인 별도의 네트워크에서 복제 될 수 있습니다. 얼마나 많은 사람들이 컴퓨터 이름 중 하나 인 "Home-PC"를 사용합니까? 사용자 이름은 서버 백엔드가 세션 데이터에서 가져온 것이므로 조작 할 수 없습니다. 토큰의 경우 사용자 자동 서명을위한 쿠키에 토큰을 생성하는 데 페이지의 세션 토큰을 생성하는 동일한 방법을 사용해야합니다. 마지막으로 사용자가 자격 증명의 유효성을 다시 확인해야하는 경우 datetime 코드가 추가됩니다. 이 날짜 시간을 며칠 내에 유지하는 사용자 로그인에서 업데이트하거나 마지막 로그인과 상관없이 만료되도록 설정하십시오 (예 : 디자인이 지정되는 경우).

    이렇게하면 자동 로그인을 알고있는 사용자의 MAC 및 호스트 이름을 체계적으로 스푸핑 할 수 없습니다. 사용자가 암호, 일반 텍스트 또는 다른 방법으로 쿠키를 보관하지 마십시오. 세션 토큰과 마찬가지로 각 페이지 탐색에서 토큰을 재생성하십시오. 이렇게하면 공격자가 유효한 토큰 쿠키를 얻어 로그인 할 수있는 가능성이 크게 줄어 듭니다. 어떤 사람들은 공격자가 희생자에게서 쿠키를 훔쳐서 세션 재생 공격을하여 로그인 할 수 있다고 말하려고합니다. 침입자가 쿠키를 훔칠 수 있다면 (가능하다면) 전체 장치가 손상되었을 것입니다. 즉, 어쨌든 장치를 사용하여 쿠키를 완전히 훔치는 목적을 무효화 할 수 있습니다. 사이트가 HTTPS (암호, CC 번호 또는 기타 로그인 시스템을 다룰 때 사용해야 함)를 통해 실행되는 한 브라우저 내에서 사용자에 대한 모든 보호 기능을 제공합니다.

    명심할 것은 자동 서명을 사용하면 세션 데이터가 만료되지 않아야한다는 것입니다. 세션을 잘못 계 속할 수있는 권한을 만료시킬 수는 있지만 시스템간에 유효성을 검사하면 세션간에 지속될 것으로 예상되는 지속적인 데이터 인 경우 세션 데이터를 다시 시작해야합니다. 영속적 인 세션 데이터와 비 영구적 인 세션 데이터를 모두 원한다면, 영속 세션 데이터를위한 다른 테이블을 사용자 이름과 함께 PK로 사용하고, 서버가 일반 세션 데이터처럼 그것을 검색하도록합니다. 다른 변수를 사용하십시오.

    이러한 방식으로 로그인이 이루어지면 서버는 세션의 유효성을 검사해야합니다. 여기서 도난 또는 손상된 시스템에 대한 기대치를 코딩 할 수 있습니다. 패턴 및 기타 세션 데이터에 대한 로그인의 예상 결과로 인해 시스템이 하이재킹되었거나 액세스를 얻기 위해 쿠키가 위조 된 것으로 결론 내릴 수 있습니다. 여기서 ISS Tech는 계정 잠금 또는 자동 서명 시스템에서 사용자 자동 제거를 트리거하는 규칙을 설정하여 공격자가 성공한 방법과이를 차단하는 방법을 사용자가 충분히 파악할 수 있도록합니다.

    닫기 유의 사항으로, 사용자가 올바르게 확인하고 이것이 발생했음을 인정할 때까지 자동 시도가 비활성화되어 임계 값을 초과 한 복구 시도, 암호 변경 또는 로그인 실패가 발생했는지 확인하십시오.

    내 대답에 누군가가 코드를 내주길 원한다면 사과드립니다. 여기서 일어날 일은 아닙니다. PHP, jQuery 및 AJAX를 사용하여 내 사이트를 실행하며 Windows를 서버로 사용하지 않는다고 말할 것입니다.

  9. ==============================

    9.내 솔루션은 이와 같습니다. 그것은 100 % 방탄이 아니지만 대부분의 경우 당신을 구할 것이라고 생각합니다.

    내 솔루션은 이와 같습니다. 그것은 100 % 방탄이 아니지만 대부분의 경우 당신을 구할 것이라고 생각합니다.

    사용자가 성공적으로 로그인하면이 정보가있는 문자열을 만듭니다.

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

    $ data를 암호화하고 HttpOnly로 유형을 설정하고 쿠키를 설정하십시오.

    사용자가 사이트를 다시 방문하면 다음 단계를 따르십시오.

    사용자가 로그 아웃 한 경우이 쿠키를 삭제하십시오. 사용자가 다시 로그인하면 새 쿠키를 만듭니다.

  10. ==============================

    10.암호화 된 콘텐츠를 쿠키에 저장하는 개념은 해킹을 수행하는 데 필요한 암호화 된 버전 일 때 이해할 수 없습니다. 내가 뭔가를 놓친다면, 제발 의견.

    암호화 된 콘텐츠를 쿠키에 저장하는 개념은 해킹을 수행하는 데 필요한 암호화 된 버전 일 때 이해할 수 없습니다. 내가 뭔가를 놓친다면, 제발 의견.

    이 접근법을 '기억하기'로 삼을 생각입니다. 문제가 있으면 의견을 말하십시오.

    내가 볼 수있는 유일한 취약점은 다음과 같습니다.

  11. ==============================

    11.나는 모든 해답을 읽고 여전히 내가해야 할 일을 추출하기가 어려웠다. 그림이 1k 단어의 가치가 있다면 Barry Jaspan의 향상된 영구 로그인 쿠키 모범 사례를 기반으로 다른 사람이 안전한 영구 저장소를 구현하는 데 도움이되기를 바랍니다.

    나는 모든 해답을 읽고 여전히 내가해야 할 일을 추출하기가 어려웠다. 그림이 1k 단어의 가치가 있다면 Barry Jaspan의 향상된 영구 로그인 쿠키 모범 사례를 기반으로 다른 사람이 안전한 영구 저장소를 구현하는 데 도움이되기를 바랍니다.

    질문, 피드백 또는 제안 사항이있는 경우 보안 영구 로그인을 구현하려는 초보자를 반영하여 다이어그램을 업데이트하려고합니다.

  12. ==============================

    12."Keep Me Logged In"기능을 구현한다는 것은 사용자가 의미하는 바를 정확하게 정의해야 함을 의미합니다. 가장 단순한 경우, 세션을 훨씬 더 긴 시간 제한 (2 시간 대신 2 일 (말))이 필요하다는 의미로 사용합니다. 이를 위해서는 데이터베이스에 고유 한 세션 저장 영역이 필요하므로 세션 데이터에 대한 사용자 정의 만료 시간을 설정할 수 있습니다. 그런 다음 브라우저를 닫을 때 만료되기보다는 며칠 (또는 그 이상) 지속될 쿠키를 설정해야합니다.

    "Keep Me Logged In"기능을 구현한다는 것은 사용자가 의미하는 바를 정확하게 정의해야 함을 의미합니다. 가장 단순한 경우, 세션을 훨씬 더 긴 시간 제한 (2 시간 대신 2 일 (말))이 필요하다는 의미로 사용합니다. 이를 위해서는 데이터베이스에 고유 한 세션 저장 영역이 필요하므로 세션 데이터에 대한 사용자 정의 만료 시간을 설정할 수 있습니다. 그런 다음 브라우저를 닫을 때 만료되기보다는 며칠 (또는 그 이상) 지속될 쿠키를 설정해야합니다.

    "왜 2 일? 왜 2 주 아니지?"라는 질문을들을 수 있습니다. 이는 PHP에서 세션을 사용하면 자동으로 만료를 다시 밀어 내기 때문입니다. 이것은 PHP에서 세션의 만기가 실제로 유휴 시간 초과이기 때문입니다.

    이제, 그렇게 말하면서, 아마도 세션 자체에 저장하는 더 엄격한 제한 시간 값을 구현할 것이고, 2 주 정도 지나면 세션을 무효화하고이를 볼 수있는 코드를 추가 할 것입니다. 아니면 적어도 그들을 로그 아웃하십시오. 이것은 사용자가 주기적으로 로그인하도록 요구된다는 것을 의미합니다. 야후! 이러다.

  13. from https://stackoverflow.com/questions/1354999/keep-me-logged-in-the-best-approach by cc-by-sa and MIT license