Regenerate PHP session id
I like secure PHP applications, and I don't like cookies. I wanted my PHP application to be cookie independent, but still wanted to use the native sessions support. Passing the session id in the url is the only option, but it's not secure..
Note: An updated version of this article can be found here.
But what if we encrypt the whole query string, and regenerate the session id each time a user loads a page. Easy:
session_id($decryptedIdFromQuerystring);
session_start();
session_regenerate_id();
Well, true. But session_regenerate_id() does not destroy the old session.
No problem:
session_id($decryptedIdFromQuerystring);
session_start();
$tmpSession=$_SESSION;
session_destroy();
session_id(md5(microtime()));
session_start();
$_SESSION = $tmpSession;
It works, as long as the user doesn't reload the page. Because then the session id in the querystring is already destroyed.
But wait, what is the point of encrypting the query string? An attacker doesn't need the original querystring. He just needs the encrypted one, which is left all over internet since it is passed in the query string. Well, first of all: so is the cookie. And since the session id is regenerated on each request it is pretty much useless as soon as the user clicks on an internal link, or logs out. Another option is to encrypt and decrypt is using the user's IP and User-Agent. This way the attacker needs to make sure he has the same ip and User-Agent as the user. It's not impossible, but it's not easy neither. We can also ask the user to supply a pin code if he reloads the same page, with a session id that is used before. It all depends on how secure you want the system.
Well, here is my solution:
ini_set('session.use_cookies', false);
session_save_path("/tmp");
if(!isset($_GET['id'])) {
session_start();
} else {
session_id($_GET['id']);
session_start();
$_SESSION['destroy'] = $_SESSION['last_id'];
$_SESSION['last_id'] = session_id();
}
$tmpSession = $_SESSION;
session_id(md5(microtime()));
session_start();
$_SESSION = $tmpSession;
if(isset($_SESSION['destroy'])) {
if(file_exists(session_save_path()."/sess_".$_SESSION['destroy'])) {
echo "Destroying session:". $_SESSION['destroy']."<br>";
unlink(session_save_path()."/sess_".$_SESSION['destroy']);
}
}
$_SESSION['count']++;
echo $_SESSION['count']."";
echo "<a href='test.php?id=".session_id()."'>reload< <a>";
This is not perfect, but it works..
Post new comment