Friday, 20 January 2012

PHP session security: Part 3 - Session ID storage on the client

Introduction
This is my third post in a series about securing PHP sessions and focuses on how to securely store the session ID stored on the client.  For more information on why you have to store the session ID on the client see my post about how PHP sessions work.

Methods of client side id storage
There are three main methods of storing the session id on the client browser which are, as a cookie, in the URL as a string parameter or in a form as POST data.

Of these three passing it in the URL is the least secure for a number of reasons.  Two main ones are that the session id is visible to anyone who can see that URL.  This doesn't just mean people looking at their screen but also if the user were to copy the URL and send it to someone and anyone who has access to their browsers history.

Passing the session id in POST data is more secure as long as a secure connection is used but can be a bit more awkward as you'll have to make every server request from the client a form submission.  This isn't the most secure method though because as I'm sure you know that when a user makes a page request to the server a page is sent back and this page is stored on the users computer.  This means that the session id that's been set in the page form (generally as a hidden field) is clearly visible in that file, although it does seem unlikely to me that anyone would actually look at this file it is still possible, more so if they are on a public computer.

The most common and secure method is to set a cookie on the clients browser as it can be easily set to only send its value over a secure connection and to the correct domain (there are many other settings too).  What makes this more secure than sending it via POST submissions is that the cookie stored on the client browser should be kept restricted by the browser so not everyone can see and read them other than the user (with the correct tools) and the site that set them.

Using only cookies
I'm going to concentrate mainly on how to secure the session id stored on the client using cookies as this is the most secure and common method using the default PHP session handler.

In PHP version 4.3.0 a setting was introduced, session.use_only_cookieswhich allows you to tell PHP to only use cookies for setting the session id and also only accept session ids sent from the browser in a cookie.  One thing to note however is that up until version 5.3.0 this defaulted to 0, meaning it would set and accept session ids using any method, but since version 5.3.0 defaults to 1 meaning it only sets and accepts session ids from cookies.

There are a few ways of setting this option so cookies are the only method the session id can be sent in, one is to set it directly in the php.ini file but if you don't have access to that you can set it in your PHP script using ini_set() (i.e. ini_set('session.use_only_cookies', 1);).

Securing the cookies
Once your application is set to only set and accept session ids via cookies you'll then need to secure the cookies, which is again not to complicated and just involves changing some settings.

You'll need to make sure the cookie is only available to the correct domain (session.cookie_domain), make sure it's only sent over a secure HTTPS connection (session.cookie_secure) and secure against any hacks that involve getting the cookie values from JavaScript injections, cross-site scripting or various other methods (session.cookie_httponly).  Conveniently there is one setting that will do all of this and a couple more (session.cookie_lifetime) which is session_set_cookie_params (i.e. session_set_cookie_params(0, '/', my-domain.com, true, true);).

Something to note about using cookies is that you are relying on the browser keeping them secure but there have been exploits in browsers before which compromise this (Internet Explorer being the main one but not the only).  As this will almost always be out of your control (possible exception being if you're building an intranet site) you shouldn't ever store any sensitive information such as the usernames, passwords or personal details in a session variable.  I'd recommend encrypting or hashing and information stored in a session variable if it's possible, although I'm aware that in a lot of cases that just wouldn't be practical or even possible.

Hopefully that's been helpful, if so let me know (also if you think I missed anything or just got something plain wrong)!

Other parts in this series:
Further reading

    No comments:

    Post a Comment