programing tip

세션 도용을 방지하는 가장 좋은 방법은 무엇입니까?

itbloger 2020. 7. 11. 10:55
반응형

세션 도용을 방지하는 가장 좋은 방법은 무엇입니까?


특히 이것은 클라이언트 세션 쿠키를 사용하여 서버에서 세션을 식별 할 때 관련됩니다.

전체 웹 사이트에 SSL / HTTPS 암호화를 사용하는 가장 좋은 방법은 무엇입니까? 중간 공격을받는 사람이 기존 클라이언트 세션 쿠키를 스니핑 할 수 없다는 것을 가장 잘 보증합니까?

세션 쿠키에 저장된 세션 값 자체에 일종의 암호화를 사용하는 것이 가장 좋습니다.

악의적 인 사용자가 컴퓨터에 물리적으로 액세스 할 수있는 경우에도 파일 시스템을 검사하여 유효한 세션 쿠키를 검색하고이를 사용하여 세션을 가로 챌 수 있습니까?


세션 값을 암호화하면 효과가 없습니다. 세션 쿠키는 이미 임의의 값이므로 암호화하면 스니핑 할 수있는 다른 임의의 값만 생성됩니다.

유일한 해결책은 HTTPS입니다. 전체 사이트에서 SSL을 수행하지 않으려는 경우 (성능 문제가있을 수 있음) 중요한 영역을 보호하는 SSL 만 사용하여 벗어날 수 있습니다. 그렇게하려면 먼저 로그인 페이지가 HTTPS인지 확인하십시오. 사용자가 로그인 할 때 일반 세션 쿠키 외에 보안 쿠키 (브라우저가 SSL 링크를 통해서만 전송한다는 의미)를 설정하십시오. 그런 다음 사용자가 "민감한"영역 중 하나를 방문하면 HTTPS로 리디렉션하고 해당 보안 쿠키가 있는지 확인하십시오. 실제 사용자에게는 세션 하이재커가 없을 것입니다.

편집 :이 답변은 원래 2008 년에 작성되었습니다. 현재 2016 년이며 전체 사이트에 SSL을 적용 할 이유가 없습니다. 더 이상 평문 HTTP가 없습니다!


SSL은 스니핑 공격에만 도움이됩니다. 공격자가 컴퓨터에 액세스 할 수 있으면 보안 쿠키도 복사 할 수 있다고 가정합니다.

최소한 오래된 쿠키는 잠시 후에 가치를 잃어 버리지 않도록하십시오. 쿠키가 작동을 멈 추면 성공적인 하이재킹 공격조차 차단됩니다. 사용자에게 한 달 이상 전에 로그인 한 세션의 쿠키가 있으면 암호를 다시 입력하십시오. 사용자가 사이트의 "로그 아웃"링크를 클릭 할 때마다 이전 세션 UUID를 다시 사용할 수 없도록하십시오.

이 아이디어가 효과가 있는지 확실하지 않지만 여기에 있습니다. 세션 쿠키에 일련 번호를 추가하십시오.

SessionUUID, 일련 번호, 현재 날짜 / 시간

이 문자열을 암호화하여 세션 쿠키로 사용하십시오. 쿠키의 유효 기간이 5 분인 경우 시리얼 번호를 정기적으로 변경 한 후 쿠키를 다시 발행하십시오. 원하는 경우 모든 페이지보기에서 다시 발행 할 수도 있습니다. 서버 측에서 해당 세션에 대해 마지막으로 발행 한 일련 번호를 기록하십시오. 누군가 일련 번호가 잘못된 쿠키를 보낸 경우 공격자가 쿠키를 사용 중일 수 있으므로 세션 UUID를 무효화하고 사용자에게 비밀번호를 다시 입력 한 다음 새 쿠키를 다시 발행하도록 요청합니다.

사용자에게는 둘 이상의 컴퓨터가있을 수 있으므로 둘 이상의 활성 세션이있을 수 있습니다. 컴퓨터간에 전환 할 때마다 다시 로그인하도록하는 작업을 수행하지 마십시오.


PHP 보안에 관한 책을 읽어 보셨습니까? 추천.

SSL 인증이 아닌 사이트에 대해 다음 방법으로 많은 성공을 거두었습니다.

  1. 동일한 계정에서 여러 세션을 허용하지 않고 IP 주소만으로이 세션을 확인하지 않도록하십시오. IP 주소, HTTP_USER_AGENT 등 데이터베이스에서 사용자 세션과 함께 저장된 로그인시 생성 된 토큰으로 확인하십시오.

  2. 관계 기반 하이퍼 링크 사용 링크 생성 (예 : http://example.com/secure.php?token=2349df98sdf98a9asdf8fas98df8 ) 링크에 x-BYTE (기본 크기) 임의의 소금에 절인 MD5 문자열이 추가됩니다. 토큰은 요청 된 페이지에 해당합니다.

    • 다시로드하면 몇 가지 검사가 수행됩니다.
    • 원래 IP 주소
    • HTTP_USER_AGENT
    • 세션 토큰
    • 당신은 요점을 얻습니다.
  3. 짧은 수명 세션 인증 쿠키. 위에서 게시 한 것처럼 세션 유효성에 대한 직접적인 참조 중 하나 인 보안 문자열을 포함하는 쿠키는 좋은 생각입니다. x 분마다 만료되도록하고 해당 토큰을 재발급하고 새 데이터와 세션을 다시 동기화하십시오. 데이터가 일치하지 않으면 사용자를 로그 아웃하거나 세션을 다시 인증하도록하십시오.

나는 결코 주제에 관한 전문가가 아니며,이 특정 주제에 대해 약간의 경험이 있었으며,이 중 일부는 누군가를 도울 수 있기를 바랍니다.


// Collect this information on every request
$aip = $_SERVER['REMOTE_ADDR'];
$bip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$agent = $_SERVER['HTTP_USER_AGENT'];
session_start();

// Do this each time the user successfully logs in.
$_SESSION['ident'] = hash("sha256", $aip . $bip . $agent);

// Do this every time the client makes a request to the server, after authenticating
$ident = hash("sha256", $aip . $bip . $agent);
if ($ident != $_SESSION['ident'])
{
    end_session();
    header("Location: login.php");
    // add some fancy pants GET/POST var headers for login.php, that lets you
    // know in the login page to notify the user of why they're being challenged
    // for login again, etc.
}

What this does is capture 'contextual' information about the user's session, pieces of information which should not change during the life of a single session. A user isn't going to be at a computer in the US and in China at the same time, right? So if the IP address changes suddenly within the same session that strongly implies a session hijacking attempt, so you secure the session by ending the session and forcing the user to re-authenticate. This thwarts the hack attempt, the attacker is also forced to login instead of gaining access to the session. Notify the user of the attempt (ajax it up a bit), and vola, Slightly annoyed+informed user and their session/information is protected.

We throw in User Agent and X-FORWARDED-FOR to do our best to capture uniqueness of a session for systems behind proxies/networks. You may be able to use more information then that, feel free to be creative.

It's not 100%, but it's pretty damn effective.

There's more you can do to protect sessions, expire them, when a user leaves a website and comes back force them to login again maybe. You can detect a user leaving and coming back by capturing a blank HTTP_REFERER (domain was typed in the URL bar), or check if the value in the HTTP_REFERER equals your domain or not (the user clicked an external/crafted link to get to your site).

Expire sessions, don't let them remain valid indefinitely.

Don't rely on cookies, they can be stolen, it's one of the vectors of attack for session hijacking.


Try Secure Cookie protocol described in this paper by Liu, Kovacs, Huang, and Gouda:

As stated in document:

A secure cookie protocol that runs between a client and a server needs to provide the following four services: authentication, confidentiality, integrity and anti-replay.

As for ease of deployment:

In terms of efficiency, our protocol does not involve any database lookup or public key cryptography. In terms of deployability, our protocol can be easily deployed on an existing web server, and it does not require any change to the Internet cookie specication.

In short: it is secure, lightweight, works for me just great.


There is no way to prevent session hijaking 100%, but with some approach can we reduce the time for an attacker to hijaking the session.

Method to prevent session hijaking:

1 - always use session with ssl certificate;

2 - send session cookie only with httponly set to true(prevent javascript to access session cookie)

2 - use session regenerate id at login and logout(note: do not use session regenerate at each request because if you have consecutive ajax request then you have a chance to create multiple session.)

3 - set a session timeout

4 - store browser user agent in a $_SESSION variable an compare with $_SERVER['HTTP_USER_AGENT'] at each request

5 - set a token cookie ,and set expiration time of that cookie to 0(until the browser is closed). Regenerate the cookie value for each request.(For ajax request do not regenerate token cookie). EX:

    //set a token cookie if one not exist
    if(!isset($_COOKIE['user_token'])){
                    //generate a random string for cookie value
        $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));

        //set a session variable with that random string
        $_SESSION['user_token'] = $cookie_token;
        //set cookie with rand value
        setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
    }

    //set a sesison variable with request of www.example.com
    if(!isset($_SESSION['request'])){
        $_SESSION['request'] = -1;
    }
    //increment $_SESSION['request'] with 1 for each request at www.example.com
    $_SESSION['request']++;

    //verify if $_SESSION['user_token'] it's equal with $_COOKIE['user_token'] only for $_SESSION['request'] > 0
    if($_SESSION['request'] > 0){

        // if it's equal then regenerete value of token cookie if not then destroy_session
        if($_SESSION['user_token'] === $_COOKIE['user_token']){
            $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM));

            $_SESSION['user_token'] = $cookie_token;

            setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true);
        }else{
            //code for session_destroy
        }

    }

            //prevent session hijaking with browser user agent
    if(!isset($_SESSION['user_agent'])){
        $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
    }

    if($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']){
      die('session hijaking - user agent');
    }

note: do not regenerate token cookie with ajax request note: the code above is an example. note: if users logout then the cookie token must be destroyed as well as the session

6 - it's not a good aproach to use user ip for preventing session hijaking because some users ip change with each request. THAT AFFECT VALID USERS

7 - personally I store session data in database , it's up to you what method you adopt

If you find mistake in my approach please correct me. If you have more ways to prevent session hyjaking please tell me.


Ensure you don't use incremting integers for session IDs. Much better to use a GUID, or some other long randomly generated character string.


There are many ways to create protection against session hijack, however all of them are either reducing user satisfaction or are not secure.

  • IP and/or X-FORWARDED-FOR checks. These work, and are pretty secure... but imagine the pain of users. They come to an office with WiFi, they get new IP address and lose the session. Got to log-in again.

  • User Agent checks. Same as above, new version of browser is out, and you lose a session. Additionally, these are really easy to "hack". It's trivial for hackers to send fake UA strings.

  • localStorage token. On log-on generate a token, store it in browser storage and store it to encrypted cookie (encrypted on server-side). This has no side-effects for user (localStorage persists through browser upgrades). It's not as secure - as it's just security through obscurity. Additionally you could add some logic (encryption/decryption) to JS to further obscure it.

  • Cookie reissuing. This is probably the right way to do it. The trick is to only allow one client to use a cookie at a time. So, active user will have cookie re-issued every hour or less. Old cookie is invalidated if new one is issued. Hacks are still possible, but much harder to do - either hacker or valid user will get access rejected.


Let us consider that during the login phase the client and server can agree on a secret salt value. Thereafter the server provides a count value with each update and expects the client to respond with the hash of the (secret salt + count). The potential hijacker does not have any way to obtain this secret salt value and thus cannot generate the next hash.


AFAIK the session object is not accessible at the client, as it is stored at the web server. However, the session id is stored as a Cookie and it lets the web server track the user's session.

To prevent session hijacking using the session id, you can store a hashed string inside the session object, made using a combination of two attributes, remote addr and remote port, that can be accessed at the web server inside the request object. These attributes tie the user session to the browser where the user logged in.

If the user logs in from another browser or an incognito mode on the same system, the IP addr would remain the same, but the port will be different. Therefore, when the application is accessed, the user would be assigned a different session id by the web server.

Below is the code I have implemented and tested by copying the session id from one session into another. It works quite well. If there is a loophole, let me know how you simulated it.

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    HttpSession session = request.getSession();
    String sessionKey = (String) session.getAttribute("sessionkey");
    String remoteAddr = request.getRemoteAddr();
    int remotePort = request.getRemotePort();
    String sha256Hex = DigestUtils.sha256Hex(remoteAddr + remotePort);
    if (sessionKey == null || sessionKey.isEmpty()) {
        session.setAttribute("sessionkey", sha256Hex);
        // save mapping to memory to track which user attempted
        Application.userSessionMap.put(sha256Hex, remoteAddr + remotePort);
    } else if (!sha256Hex.equals(sessionKey)) {
        session.invalidate();
        response.getWriter().append(Application.userSessionMap.get(sessionKey));
        response.getWriter().append(" attempted to hijack session id ").append(request.getRequestedSessionId()); 
        response.getWriter().append("of user ").append(Application.userSessionMap.get(sha256Hex));
        return;
    }
    response.getWriter().append("Valid Session\n");
}

I used the SHA-2 algorithm to hash the value using the example given at SHA-256 Hashing at baeldung

Looking forward to your comments.


To reduce the risk you can also associate the originating IP with the session. That way an attacker has to be within the same private network to be able to use the session.

Checking referer headers can also be an option but those are more easily spoofed.


Protect by:

$ip=$_SERVER['REMOTE_ADDER'];
$_SESSEION['ip']=$ip;

참고URL : https://stackoverflow.com/questions/22880/what-is-the-best-way-to-prevent-session-hijacking

반응형