Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the point of unsetting the cookie during a logout from a php session?

I am developing a web application with PHP where a user will be able to have his or her own account, and the session that keeps track of the user is stored in a MySQL database. Now, after searching for an answer on how to implement this, I find that many people like to both use session_destroy() and unset the cookie. Why - wouldn't session_destroy() be enough on its own? Even the PHP manual says "In order to kill the session altogether, like to log the user out, the session id must also be unset."

My reasoning: After the user has logged out, and happens to visit just one more page on your site before leaving, the PHP script checking if the user is logged in or not will call session_start(), setting a new session cookie for the user anyway. Here's how it might look like:

// here we include some scripts and make some instances we'll need
require_once("database.php");
require_once("session.php");
$database_connection = new DB_Connection();
$session = new Session($database_connection);

// here a session cookie is sent to a user, even if he or she isn't logged in
session_start();

// finally we check if the user is logged in
$log_isLogged = false;
if(isset($_SESSION['member_id'], $_SESSION['username'])){
    $log_member_id = $_SESSION['member_id'];
    $log_username = $_SESSION['username'];
    $log_isLogged = true;
}

Sure, it is nice for when the user knows about this fact, and leaves the site before a new cookie might be set. But some sites even redirect you to a new page directly after a logout, resulting in a new session cookie - undoing what you just did.

Is my reasoning flawed in some way, or does it not really matter if you unset a session cookie or not? Maybe most developers just think along the lines that it at least can't hurt to unset it?

I am not a native speaker, so I apologize in advance for any typos and grammatical errors.

like image 500
Muuse Avatar asked Jan 19 '23 01:01

Muuse


1 Answers

The (poorly named) session_destroy() function only deletes data out of the session. It does not remove the session cookie from the browser and leaves the session_id associated with the session. session_start() only issues a new session_id to the client if one was not already supplied in the client's request. Your code is vulnerable to an attack known as session fixation, where a malicious attacker will start a session on your site to obtain a valid session_id, and then trick unsuspecting users of your site to login with the attacker's known session_id. This can be accomplished by either sending the victim a link with the session_id in the URL (if your site will accept it that way) or various other methods. Once the victim logs in, the attacker is effectively logged in as that same user as well.

In order to prevent session fixation attacks you should:

  1. On successful login, issue a brand new session_id to the client by calling session_regenerate_id().

  2. On logout, completely destroy every artifact of the session on both server and client. This means calling session_destroy() and unsetting the client cookie with setcookie().

  3. Make sure your site does not ever expose session_id in the URL or accept a session_id supplied in the URL.

  4. Make sure your session_ids are long and random enough that they cannot practically be guessed by a would be attacker.

  5. Make sure your site is not vulnerable to cross site scripting attacks, which would allow attackers to steal valid session_ids from already logged-in users.

  6. Make sure your login occurs over https and the session cookie is marked secure. All communication related to sessions should occur over https. The client's session_id must never be sent over http because that would expose it during transit.

Further reference: OWASP Top Ten page on session management

like image 132
Asaph Avatar answered Feb 08 '23 15:02

Asaph