Home arrow PHP arrow Page 4 - Sessions and Cookies

Session Hijacking - PHP

If you want to gain a better understanding of PHP security, you've come to the right place. This article covers ways to prevent cookie theft and session hijacking, among other topics. It is excerpted from chapter four of the book Essential PHP Security, written by Chris Shiflett (O'Reilly; ISBN: 059600656X). Copyright © 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

  1. Sessions and Cookies
  2. Cookie Theft
  3. Session Fixation
  4. Session Hijacking
By: O'Reilly Media
Rating: starstarstarstarstar / 18
June 07, 2007

print this article



The most common session attack is session hijacking. This refers to any method that an attacker can use to access another user’s session. The first step for any attacker is to obtain a valid session identifier, and therefore the secrecy of the session identifier is paramount. The previous sections on exposure and fixation can help you to keep the session identifier a shared secret between the server and a legitimate user.

The principle of Defense in Depth (described in Chapter 1) can be applied to sessions—some minor safeguards can offer some protection in the unfortunate case that the session identifier is known by an attacker. As a security-conscious developer, your goal is to complicate impersonation. Every obstacle, however minor, offers some protection.

The key to complicating impersonation is to strengthen identification. The session identifier is the primary means of identification, and you want to select other data that you can use to augment this. The only data you have available is the data within each HTTP request:

  GET / HTTP/1.1
  Host: example.org
  User-Agent: Firefox/1.0
  Accept: text/html, image/png, image/jpeg, image/gif, */*
  Cookie: PHPSESSID=1234

You want to recognize consistency in requests and treat any inconsistent behavior with suspicion. For example, while theUser-Agentheader is optional, clients that send it do not often alter its value. If the user with a session identifier of1234has been using Mozilla Firefox consistently since logging in, a sudden switch to Internet Explorer should be treated with suspicion. For example, prompting for the password is an effective way to mitigate the risk with minimal impact to your legitimate users in the case of a false alarm. You can check forUser-Agentconsistency as follows:



  if (isset($_SESSION['HTTP_USER_AGENT']))
      /* Prompt for password */


I have observed that some versions of Internet Explorer send a differentAccept header depending upon whether the user refreshes the browser, soAcceptshould not be relied upon for consistency.

Requiring a consistentUser-Agenthelps, but if the session identifier is being propagated in a cookie (the recommended approach), it is reasonable to assume that, if an attacker can capture the session identifier, he can most likely capture the value of all other HTTP headers as well. Because cookie disclosure typically involves a browser vulnerability or cross-site scripting, the victim has most likely visited the attacker’s web site, disclosing all headers. All an attacker must do is reproduce all of these to avoid any consistency check that uses HTTP headers.

A better approach is to propagate a token in the URL—something that can be considered a second (albeit much weaker) form of identification. This propagation takes some work—there is no feature of PHP that does it for you. For example, assuming the token is stored in$token, all internal links in your application need to include it:


  $url = array();
  $html = array();

  $url['token'] = rawurlencode($token);
  $html['token'] = htmlentities($url['token'], ENT_QUOTES, 'UTF-8');


  <a href="index.php?token=<?php echo $html['token']; ?>">Click Here</a>

To make propagation a bit easier to manage, you might consider keeping the entire query string in a variable. You can append this variable to all of your links, which makes it easy to refactor your code later, even if you don’t implement this technique initially.

The token needs to be something that cannot be predicted, even under the condition that the attacker knows all of the HTTP headers that the victim’s browser typically sends. One way to achieve this is to generate the token using a random string:


  $string = $_SERVER['HTTP_USER_AGENT'];
  $string .= 'SHIFLETT';

  $token = md5($string);
  $_SESSION['token'] = $token;



When you use a random string (SHIFLETTin this example), prediction is impractical. In this case, capturing the token is easier than predicting it, and by propagating the token in the URL and the session identifier in a cookie, multiple attacks are needed to capture both. The exception is when the attacker can observe the victim’s raw HTTP requests as they are sent to your application, because this discloses
everything. This type of attack is more difficult (and therefore less likely), and it can be mitigated by using SSL.

Some experts warn against relying on the consistency ofUser-Agent. The concern is that an HTTP proxy in a cluster can modifyUser-Agentinconsistently with other proxies in the same cluster.

If you do not want to depend onUser-Agentconsistency, you can generate a random token:


  $token = md5(uniqid(rand(), TRUE));
  $_SESSION['token'] = $token;


This approach is slightly weaker, but it is much more reliable. Both methods provide a strong defense against session hijacking. The appropriate balance between security and reliability is up to you.

>>> More PHP Articles          >>> More By O'Reilly Media

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort


- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates


Dev Shed Tutorial Topics: