Session Fixation

Session fixation is an attack where the attacker provides a user with a valid session identifier. It is like the opposite of session hijacking. Instead of stealing the user's session ID (so that both the attacker and user are sharing a session), the attacker gives the user a session ID to use (so that both the attacker and the user are sharing a session). Both attacks are used for the same purposes--the attacker gains an authenticated session which can access restricted information and actions.

In a session fixation attack, the attacker creates a session with the target website, but they do not bother logging in. They just need to get a session created and know the session ID. Next, the attacker tricks a user into using the attacker's session ID. (More on how this is possible in a moment.) Then when the user next logs in to the website, unaware that they are using someone else's session ID, the website will bestow the attacker's session with the authentication. Now, the attacker can visit the access-restricted pages using the same session.

The simplest session fixation attacks rely on session IDs being accepted from URLs or form data. If a website allows a session ID in a URL, then it is simply a matter of getting a user to click on that link.

http://yoursite.com/login.php?PHPSESSID=qvidf3pweno6c12whk3hk26oxs0hjke0

The link does not even need to go to a login page or an access-restricted page. Any page on the website's domain will work, as long as the website attaches the attacker's session ID to the user.

It has become uncommon to maintain session IDs in URL strings, in part due to session fixation. For example, in PHP, default configurations were changed in 2002 to make it more difficult to turn on this option.

However, this does not mean that session fixation is not possible now. It is still possible if an attacker has the ability to set the user's browser cookie to their session ID. Most often this is done using Cross-Site Scripting (XSS).

http://yoursite.com/page.php?q=<script>document.cookie="PHPSESSID=qvidf3pweno6c12whk3hk26oxs0hjke0";</script>

A more sophisticated attack could set the cookie data in other ways, such as by altering the response data that the user receives. This could be done as a Man in the Middle attack. The response is allowed to include a Set-Cookie directive.

Set-Cookie: PHPSESSID=qvidf3pweno6c12whk3hk26oxs0hjke0

Session Fixation Preventions

Never accept session identifiers as GET or POST variables. Only accept session identifiers from cookies. This removes the easiest way to set a session ID.

The next prevention is to ensure that cookies cannot be set using Cross-Site Scripting (XSS) by using HttpOnly cookies. JavaScript will not be allowed to access HttpOnly cookies. Even if a site is still vulnerably to XSS in other ways, if cookies are disallowed for JavaScript use then session fixation will not be possible.

// In php.ini configuration
session.use_only_cookies = 1
session.cookie_httponly = 1

These values can be set in the php.ini file or (in PHP 7) as options when the session is started. (See cookie and session options)


Regenerating session identifiers

The single best defense against session fixations it regenerate session identifiers after login. Regenerating a session ID gives the user a fresh session ID, instead of using the attacker-provided session ID. When the user is authenticated, their authorization will be stored on the new session ID. The attacker will have the old one and it will not have been granted access.

<?php
 function after_successful_login() {
   session_regenerate_id();
   $_SESSION['logged_in'] = true;
   $_SESSION['last_login'] = time();
 }
?>

Fork me on GitHub