Документация
HTML CSS PHP PERL другое

Session Management

 
Previous
Table of Contents
Next

Session Management

From the discussion of user management, cookies, and sessions in Chapter 19, "Cookies and Sessions," you learned that there was more to effective and secure session management than just making calls to the session_start function. In particular, we face a number of security concerns when working with sessions, and some configuration options that we will want to make sure we have set properly.

Configuration

As discussed in Chapter 19, php.ini has a number of configuration options for sessions in PHP to control the exact functionality. For our web application samples, we use the following settings:

  • session.auto_start = 0

    We will always explicitly start sessions ourselves.

  • session.name = "SAMPLESESSION"

    We will just use something other than the default here.

  • session.save_handler = "files"

    Our samples are not complicated enough to require custom session storage, although it would be an excellent exercise for you to implement.

  • session.save_path = "/home/httpd/webapps/sessiondata" (Unix) or "d:\webapps\sessiondata" (Windows)

    The exact location depends on where we place our web applications and documents for our web server.

  • session.gc_probability = 1 and session.gc_divisor = 10

    This gives us a 10-percent chance of having the garbage collector started for or any page request, which is in fact quite often. However, we do not expect to have high traffic for our samples, so we need a higher value to ensure that this is started often enough. For real-world web applications with many users, we would reduce this to something more similar to the defaults of 1 and 100.

  • session.cookie_lifetime = 0, session.cookie_path = /, session.cookie_domain = (empty), and session.cookie_secure = (empty)

    These values correspond to the parameters sent to the setcookie function. We will leave these at their default values because we only want a simple session cookie that expires when users close their browser(s).

  • session.use_trans_sid = 0

    We will leave this at its default value for security reasons so that people must use session cookies to visit our web application.

  • session.use_cookies = 1 and session.use_only_cookies = 1

    These settings permit us to use session cookies for user management and require us to use cookies rather than other possibilities (such as the trans_sid mentioned previously). This helps us ensure a higher level of security for users.

The one configuration option not mentioned in the preceding list is the session.gc_maxlifetime value, which defaults to an extremely short 1,440 seconds (24 minutes). The exact value we will use for this depends on what sort of web application we are writing. For an E-Commerce store where we are dealing with sensitive information, we will want to keep this to a still reasonably short value, perhaps 3,600 seconds (1 hour), whereas for something a little less sensitive, such as a message board or web log system, we could let this be something much larger, such as 86,400 (1 day).

We can either change the value of session.gc_maxlifetime in the php.ini files we use for each application, or we can use the ini_set function in your scripts before we call the session_start function.

Security

To provide more optional security for users and web applications, we will do a little bit more than just call session_start at the top of each script. As shown in Chapter 19, we are particularly worried about two aspects of session security: session fixation (how hackers attempt to determine a user's session ID) and minimizing damage after a session is compromised.

We try to minimize session fixation by using the following code to create our sessions:

session_start();
/**
 * Try to prevent session fixation by ensuring that we created
 * the session ID.
 */
if (!isset($_SESSION['created']))
{
  session_regenerate_id();
  $_SESSION['created'] = TRUE;
}

We will try to more closely associate the user with his session ID by using the User-Agent string from the HTTP request, as follows:

define('USER_AGENT_SALT', 'PosterStore');

/**
 * Try to limit the damage from a compromised session ID by
 * saving a hash of the User-Agent: string with another
 * value.
 */
if (!isset($_SESSION['user_agent']))
{
  /**
   * create a hash user agent and a string to store in session
   * data.
   */
  $_SESSION['user_agent'] =
      md5($_SERVER['HTTP_USER_AGENT'] . USER_AGENT_SALT);
}
else
{
  /**
   * verify that the user agent matches the session data
   */
  if ($_SESSION['user_agent'] !=
          md5($_SERVER['HTTP_USER_AGENT'] . USER_AGENT_SALT))
  {
    /**
     * Possible Security Violation.  Tell the user what
     * happened and refuse to continue.
     */
    throw new SessionCompromisedException();
  }
}

Putting It All Together

After we have configured php.ini, we can write a session.inc file that we will include at the top of any of our scripts that require sessions. This file performs the three critical tasks of (last-minute) configuration, session initialization, and worrying about security. The complete contents of the version we will use for one of our samples are as follows:

<?php
/**
 * session.inc
 *
 * Author: Marc Wandschneider
 *
 * This file will contain the core session handling code that
 * we will use in our poster store web application.  We will
 * do a few extra things when we create a session to try to
 * avoid some common security problems:
 *
 * 1. We will add a 'created' variable to the session data to
 *    verify that we were the ones who created this session.
 *    (This helps avoid session fixation attacks.)
 *
 * 2. We will record a hash of the client's USER_AGENT string
 *    along with another string to reduce the chance of a
 *    compromised session ID being used successfully.
 */
define('USER_AGENT_SALT', 'PosterStore');

/**
 * One of these sessions can last 60 minutes
 */
ini_set('session.gc_maxlifetime', 3600);
session_start();

/**
 * Try to prevent session fixation by ensuring that we created
 * the session ID.
 */
if (!isset($_SESSION['created']))
{
  session_regenerate_id();
  $_SESSION['created'] = TRUE;
}

/**
 * Try to limit the damage from a compromised session ID by
 * saving a hash of the User-Agent: string with another
 * value.
 */
if (!isset($_SESSION['user_agent']))
{
  /**
   * create a hash user agent and a string to store in session
   * data.
   */
  $_SESSION['user_agent'] =
      md5($_SERVER['HTTP_USER_AGENT'] . USER_AGENT_SALT);
}
else
{
  /**
   * verify that the user agent matches the session data.
   */
  if ($_SESSION['user_agent'] !=
          md5($_SERVER['HTTP_USER_AGENT'] . USER_AGENT_SALT))
  {
    /**
     * Possible Security Violation.  Tell the user what
     * happened and refuse to continue.
     */
    throw new SessionCompromisedException();
  }
}

?>


Previous
Table of Contents
Next
© 2000- NIV