Page 1 of 1

Securing Cookies: Mini Tutorial/Script

Posted: Wed Sep 25, 2002 11:00 am
by nielsene
As a spin-off from an earlier thread, I've been working out a php implementation of the suggestions made in Dos and Don'ts of Client Authentication on the Web

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";  

?>
Notes: the cookie itself is still sent in plaintext across the network in this example, but any attempt to modify it will be detect. Tracking IPs will help avoid replay attacks, which I'll add shortly.

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.

Posted: Wed Sep 25, 2002 11:24 am
by JPlush76
I'm using this sample in my new ecommerce package I'm making, I'll put an example up later today :)

Posted: Wed Sep 25, 2002 12:43 pm
by Coco
looks good... ill give it a spin, hopefully it will solve my session problems

*feels chuffed, actually understands the whole of that script*

Posted: Wed Sep 25, 2002 2:00 pm
by llimllib
chuffed? is that british slang?

Oh, and script looks awesome...I may have to put it into service.

Posted: Wed Sep 25, 2002 2:11 pm
by Takuma
I live in UK but never heard of chuffed... :lol:
Script is just amazing... I might implement to my website Thanks alot :D

Posted: Wed Sep 25, 2002 2:21 pm
by JPlush76
I put the script into my ecom site and it works like a dream except if I manually tamper with the cookie it doesn't let me access the page, but it doesn't give me the tamper msg either

other than that its a score holmes

Posted: Wed Sep 25, 2002 2:29 pm
by Coco
chuffed = happy

Posted: Wed Sep 25, 2002 3:04 pm
by nielsene
I'm glad people are finding this useful, I hope to have the next version out later this week. There will probably be two tracks: one for autologin systems and one for use with ephemeral session logins. I'm finidng that the two diverge enough to require seperate scripts instead of small customizations.

Anyone have any questions/concerns about the script that I should address whil working on it?

Posted: Wed Sep 25, 2002 3:48 pm
by nielsene
New, Improved version availible at
http://ballroom-dev.mit.edu/compinabox/cookie.phps

This lacks the IP test, but can be used to protect the seesionid from tampering now as well as operating in several modes. You'll see a series of configureation values at the top of the file. For instance, an autologin script would probably use

Code: Select all

$usesSessions=TRUE;
$clientStoreCookie=TRUE;
$cookieDuration= 45 * 24 * 60 *60;//  (1.5 months)
$cookieExtend=TRUE;
$sslOnly=0;
$cookieData="user_id";
Under this approach the cookie will persist after the user closes the browser and will be valid for 45 days after the last visit. Alternative you could set teh cookieDuration much longer (such as 2 years) and then set cookieExtend to FALSE

A high security session site might use

Code: Select all

$usesSessions=TRUE;
$clientStoreCookie=FALSE;
$cookieDuration= 10 *60; // (10 minutes)
$cookieExtend=TRUE;
$sslOnly=1;
$cookieData=""; // defaults to session_id()
This site will detect attempts to change the id of the session in either the full_cookie cookie or in the session cookie sent by PHP. The users login lasts for 10 minutes since his last activity, so there is a minimal window for attack should the user not logout, when they leave the site. This is useful on a site where you expect short bursts of activity or long periods of sustained use. ClientStoreCookie is set to false to avoid the cookie being written to the clients disc for possible evil javascript re-exporting it to someone else.

Medium security session sites should problaby set the lifetime to about 8 hours and not extend the cookie.

I haven't tested all the paths through the code yet, but its typically working for me in different configurations. I'll add the options to enforce IP sameness next and then its probably done....

Posted: Tue Aug 19, 2003 10:45 am
by m3rajk
i take it you're a grad/doctoral student at mit?

it looks good. the reason i didn't use sessions is i don't know how to adjust the duration.

this looks much easier in setting duration.

Posted: Tue Aug 19, 2003 11:02 am
by nielsene
I was M.Eng student at MIT until last february. One of my friends wrote the linked article about proper use of authenticators (course I found it with a google search and didn't know he had done that...)

There's several things that should be done to the script. I'm hoping to get back to it some time. First I'ld like to library/class it up basically some sort of interface like, especially for use for securing regular sessions, but I'm in the middle of implementing a massive set of new features on my main application in order to gain a factor of 10 increase in user-base with an end of week deadline.

Posted: Tue Aug 19, 2003 11:08 am
by m3rajk
that's definitely a much higher priority.

but the mit thing explains a bit about security. i know a handful of people that went/go to mit. they're all freaks about security... i'd call them paranoid, then that'd be the kettle calling the pot...

Posted: Tue Aug 19, 2003 11:14 am
by nielsene
m3rajk wrote: but the mit thing explains a bit about security. i know a handful of people that went/go to mit. they're all freaks about security.
That comes from having Ron Rivest (the R or RSA) leading recitation section in the intro computer engineering course :)

Posted: Tue Aug 19, 2003 11:22 am
by m3rajk
lol. that explains it even better.

Posted: Sun Aug 24, 2003 2:18 pm
by wmasterj
I just want to thank nielsene for sharing that script with us. It sure learned me alot. I'm not gonna read that article you friend wrote though... :) but thx!