Notes on PHP Session Security

Summarizing a discussion from here – things to watch out for when using sessions for your sites login system;

1. Shared web servers – anyone else on the server can read your session files (typically in the /tmp directory) if PHP is running as an Apache module (so the session files belong to the web user) and possibly when PHP is used as a CGI (depending on how sessions are implemented).

Someone browsing the session files (probably) won’t know the site the server the sessions apply to (so may not be able to use a username / password combination they found) but you may still be putting sensitive info (like credit card details) somewhere for all to see. Plus they’ve got a list of valid session IDs…

If you’re just storing passwords in the session, you can get away with this by using md5() (preferably twice) to one-way encypt the password. This doesn’t help though if you need to recover the value of a session variable.

Using a custom session handler to store the sessions in a database is probably the best solution. You might consider MySQL HEAP tables if performance is an issue (assuming MySQL running on same machine as Apache). If it gets to very high traffic, it’s time to think about getting your own server…

2. XSS exploits (and session hijacking) – using JavaScript users can be fooled into giving away their active session_id.

All someone needs to “hijack” a session is the unique session id. It’s like the key to a railway station locker. The locker doesn’t check you’re the valid owner of the key, before allowing you to open it so anyone with the key can get in.

Research XSS and how to prevent it.

Accept that session hijacking cannot be entirely prevented (checks on IP address, for example, is foiled by AOL, who assign a new client IP on more or less every page request) so double check “critical actions” a user can perform when logged in e.g. when changing password – require the old password, which the session hijacker will (hopefully) not know. Displaying credit card infomation – do like Amazon and only display the last four digits. Basically limit the damage someone can do if they hijack a session.

3. Session IDs in URL (and hijacking) – if you’re using session IDs in the URL (as opposed to a session cookie), make sure offsite links do not contain the session ID (or the remote site will be able to hijack) – PHP should take care of this. Also your visitors may give away the session ID in the referrer field – ideally pass off site links through a redirect page, to elimate the referrer (although, unfortunately, some browsers keep the last 3 pages viewed I believe – unsure of facts).

Ideally, don’t pass session ids in the URL – require users to accept a cookie if they need to “log in”.

4. Session Fixation (pre-hijacking) (see http://www.acros.si/papers/session_fixation.pdf).

If you assign a session to a visitor to your site, before they are logged in (for example for clickpath analysis), make sure that you assign them a new session id when they do login, so that if someone pre-generated the initial session id for them, they won’t get the new ID.

For PHP 4.2.0+, see session_regenerate_id() (in particular the user submitted comments). For PHP < 4.2.0, you'll have to destroy the session and re-create it when the user logs in, carrying any stored data between the two. The session_id() function may also be useful (haven’t explored it in this context myself).

5. Sniffing Packets (use SSL [HTTPS]) – a session ID can be “sniffed” between the client and your server. If it’s a site where money is changing hands or other sensitive personal information is involved, SSL is a requirement.

Otherwise, without SSL, you have to live with the risk (just like you do every time you use that FTP client…).

6. Cookies are not for session data – on a related note, don’t use cookies for store sensitive information.

Cookie data, unlike sessions, gets stored on the client site. Apart from the “sniffing risk”, a large majority of Windows users have little idea of security and may be “owned by haxor”.

Otherwise, cookies (aside from session cookie PHP creates for you) are generally meant for long term (i.e. between visits) data persistance (e.g. “Remember Me”) rather than “active session” persistance.

There’s probably more things to watch out for (or facts to correct) – suggestions appreciated.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.