Secure PHP sessions?
Note: This article contains slightly outdated code. For some more up-to-date PHP snippets take a look here
Todays post will be about security, again. Most fresh developers don't focus on security when they develop applications. Many of them don't eaven know what threats that are out there.
My focusing on secure PHP sessions started with a disussion on a norwegian PHP IRC channel. One of my fellow chatters stated that if a session key was disclosed, hijacking the session would be easy as pie, just create a cookie containing the key.
I replyed (mabye jumping in water way over my head) that if that was the case, the application was poorly written. And in my oppinion, I still think this is the case. Altough it's not possible to be 100% secure, there are some methods that will improve the security of your application.
Changing the session key
This is important, in my oppinion you should change the session key for each new request the user makes. If a someone should get the hold of a session key, most likely it will be expired.
< ?php
session_start();
echo "Old session ID: ".session_id();
// copy the old session data
$oldSessionData = $_SESSION;
// destroy and recreate the session
session_destroy();
session_start();
// copy the data back to the session
$_SESSION = $oldSessionData;
echo "New session ID: ".session_id();
?>
This script will return something like this:
27981ed0f35f1f8998037fd60ec56
New session ID: ff627981ed0f35f1f8998037fd60ec56
Let us assume that a hacker would find a users session key. If the user has made another request to the server, the key the hacker holds will be useless.
Checking the user-agent
The user-agent is an indentification string sendt by the browser when it requests a page. Although I don't think you should trust HTTP headers sendt by the client, I feel that checking the user-agent for changes should be done. And it requires more work from the hacker to successfully hijack a session.
< ?php
if(!isset($_SESSION['ua'])) {
$_SESSION['ua'] = md5($_SERVER['HTTP_USER_AGENT']);
} else {
if($_SESSION['ua'] != md5($_SERVER['HTTP_USER_AGENT'])) {
echo "Your user-agent has changed, please login again.";
session_destroy();
exit(0);
}
}
?>
Checking the IP address
Checking the IP address can be done the same way as checking the user-agent, but in my oppinon the user should be able to disable this check upon login, since many users are behind proxy servers, and therefore their IP address could change during the session.
Using Secure Socket Layer
Secure Socket Layer (SSL) is used to encrypt the HTTP traffic between the server and the client. It requires some work from the server administrator to enable, but will boost the security alot. This will prevent a hacker from listening to your HTTP traffic, and stealing your session id or other sensitive information.
Teaching the user to log out
The log out link is there for a reason. When you push it, all session data should be removed, and a hacker will not (should not) be able to continue the session no matter what.
For example, if two hosts arrive a server at the same time
while using the same IP via NAT, and may be even lucky
enough to have the same random number
How PHP make them to use different session ID?
or in fact PHP session is not 100% safe enough?
- reply
Submitted by Eric (not verified) on Fri, 01/04/2008 - 12:43.In that case (extremely unlikely) they will share sessions...
- reply
Submitted by xqus on Fri, 03/07/2008 - 18:46.First of all, the two events you mention are imposible to happend at the same time exactly.
And even if they could, the server always place incoming requests in a queue, so one connection would be treated first and the other would be treated later, being assigned a diferent random number for each request...
- reply
Submitted by Ryoga (not verified) on Mon, 03/24/2008 - 11:36."First of all, the two events you mention are imposible to happend at the same time exactly."
In all programming courses I've taken dealing with 'real' code, we NEVER rely on race conditions. It is always best to assume that any code that relies on something NOT happening is insecure.
Just sayin.
- reply
Submitted by Reed (not verified) on Sat, 07/26/2008 - 20:13.Which is the difference between your method (save session data, destroy session, create new session with old datas) and the function session_regenerate_id() (or why not for example session_id(md5(microtime().$_SERVER['HTTP_USER_AGENT']) ) ?
- reply
Submitted by Anonymous (not verified) on Tue, 12/09/2008 - 08:04.From the manual:
Altough it's possible since version 5.1.0 to remove the old session data. This was not the case when this post was written.
- reply
Submitted by xqus on Sat, 12/20/2008 - 22:14.I have no idea how the hacker would obtain the session id in the first place, but if they do and access the site before the legitimate user makes another request, they would then get a new session id themselves wouldn't they?
If this is so, how likely is it for the hacker to get the S_ID say if the user quits their browser without logging out?
- reply
Submitted by Louise (not verified) on Fri, 12/12/2008 - 19:55.Session id's is usually stolen from cookies, or mabye from a man in the middle attack.
But yes, you are right. They will. But this will also log out the real user, wish should sound an alarm somewhere (usually the user, maybe a hint on the session expired page?).
How likely it is for the hacker to get the session id a _really_ hard to tell. It all depends on when he has to gain on getting it. But if the user fails to log out, he got a hell of a lot more time to get it before it expires.
- reply
Submitted by xqus on Sat, 12/20/2008 - 22:18.Post new comment