It features Message Authentication Codes(MACs) to protect the cookie data and expiration time as well as not trusting the user's browser to properly expire cookies.
This is close to a working infrastructure, I hope to clean it up with some comments from you, as well as integrate it with sessions to protect the sessionid in a good way.
Now the code: filename cookie.php
Code: Select all
<?php
// this variables should live in your database configuration file, not here
$server_mac_secret = MD5("Some String, doesn't really matter what");
// check if the user sent our cookie
if(isset($_COOKIEї'full_cookie']))
{
// break up the cookie along its deliminators
$cookie_crumbs = explode('+',$_COOKIEї'full_cookie']);
$cookie_user_id = $cookie_crumbsї1];
$cookie_expTime = $cookie_crumbsї0];
$cookie_mac = $cookie_crumbsї2];
// a debugging/reporting line to help you see what's going on, remove in real code
$submessage = "User_id: $cookie_user_id<br />expTime: $cookie_expTime<br />MAC: $mac<br />\n";
// recalculate the MAC based on the values in the cookie
$check_mac = MD5($cookie_expTime."+".$cookie_user_id."+".
$server_mac_secret);
if($check_mac == $cookie_mac)
{
if (time() < $cookie_expTime)
{
$message = "good login";
// setup any variables you need, etc
} else {
// redirect to a login screen
$message = "expired login";
}
}
else
{
// handle attacks, probably destory the cookie, send email to you giving details
$message = "tampered login<br />$cookie_mac<br />$check_mac";
}
} else {
// no cookie sent
// in a real program this should redirect to a login screen
// but for now we'll assume we had successfully logged a member in and
// set up the cookie
$user_id = 14;
$expTime = time()+7200; // cookie is good for two hours from login
// create teh MAC to detect tampering
// fields are joined together by a deliminator to prevent "slicing" attacks
$mac = MD5($expTime."+".$user_id."+".$server_mac_secret);
// combine cookie data to a single variable, also using deliminators to allow exploding
$full_cookie = $expTime."+".$user_id.'+'.$mac;
// we only need to send one cookie now
setcookie("full_cookie","$full_cookie",$expTime);
// debugging/ reporting data
$message = "Set Cookie";
$submessage = "User_id: $user_id<br />expTime: $expTime<br />MAC: $mac<br />\n";
}
echo "<html><head><title>Cookie MD5 test</title></head>\n";
echo "<body>\n";
echo "<h1>$message</h1>\n";
echo "$submessage";
echo "<a href="cookie.php">Return to Page</a>\n";
echo "</body></html>\n";
?>To turn this into an "autologin" type script, you would greatly extend the expTime. To increase the security you could shorten the expTime, but reset it on every connection. Ie, the cookie is good for say 15 minutes from the last access. When coupled with session, my next project, you'll have single session cookies, that are secure against replay attacks.