Jump to content

Recommended Posts

Just a question regarding security of the PHP session cookie

In my current project I've got a logon page that - if a user logs in successfully - does a few session variables and sets the session timeout to 30 days.

 

Basically at this point I'm trying to figure out how to make sure a malicious user can't just modify a cookie to screw with me.  I was looking at the cookie using some firefox developer tools, and it *appears* that the information is encrypted on the cookie, which would pretty much solve my dilemma if that is the case.  Because all i see is a bunch of random characters under "value".

 

Otherwise i'll have to take other measures, like if i check if say $_SESSION[username] is set, and validate that, then could a user just modify the cookie to set it?  if THAT is the case, then to be more secure i'd have to validate the session info against the db and then put that into a temporary cookie that only lasts as long as the browser (so as not to bang the heck out of the DB)

 

I may be paranoid, but please indulge me.

 

to summarize i need

1) A cookie/session that isn't easily forged or tampered with

2) A way of validating aforementioned cookie/session that doesn't re-check the database every time you click on another page

Link to comment
https://forums.phpfreaks.com/topic/134861-session-cookie-securityuser-validation/
Share on other sites

while the user is browsing the site, keep in the info in SESSION. if you want to do a 'remember me' for 30 days, generate a random md5 hash, and put that in a cookie and under the user's entry in the database.

 

when the user comes to the page, and no SESSION exists, check for the remember me. if they have a cookie, and you find the match in your db, you can be pretty certain you know who they are. but i would still recommend giving them a 'limited' login. what i mean by this, is allow them to do normal 'reading' tasks, but if they want to edit anything, especially account info, make them provide their password just to make sure. once they have authenticated with their password, you can allow them full control of their account for that SESSION

That sounds like what I'm looking for.  However I must put a wrench in the works by saying There could potentially be people logged into a limited user account with the same username/password from multiple locations simultaneously.  So generating a random hash for each logon probably wouldn't work in that case.  Could I simply sha256 the password with some salt and put that into the db and cookie?

people logged into a limited user account with the same username/password from multiple locations simultaneously

Each person should have their own unique authorization so that you can track who (, what, when, where) is using the system and if necessary disable individual access.

 

The unique ID should not be static (regenerate it regularly so that someone getting the value, such as over someone's wireless network that is not encrypted, will have a limited time frame to impersonate the actual visitor) and it should be unique.

My apologies for replying so late - was out of town with no net connection... Hell...

 

Anyway I just wanted to re-iterate that there will be a main account which people will register for, then they will create sub-users which will have limited read access and some maintenance access to the system. The sub-users will be kept in a different place in the DB from the main users since less information is needed for them.  So basically the main user should be able to be logged in for longer periods (i usually set 30 days, not permanent so they don't forget their password as much) and the sub-users may end up sharing some accounts (depending on how the master user decides they should be managed).

 

So I get what you're saying about the cookie:  have a hash in a cookie match what i've put in the DB for the main user and once verified, pass info to the session var to continue from there.

 

however, I still wonder about how to handle the sub-users.  Would it be sufficient to do the same for them? And how would I handle that if some usernames are shared (potentially to multiple computers in the same room)?.

 

Thanks again.

 

 

so...i would try to keep one table of users for everything. then another table to hold the 'extra' info for the higher-level users. then a third table for remember_me, which would have:

-user_id

-cookie_hash

-expiration

this way, any one user can have several remember_me sessions. make sense?

Would it be OK to have the users all in the same table with added info but to allow null values for unnecessary info?  I had considered having a field listing "usertype" and having numeric values determine the access.

 

And at what point should i change the cookie_hash?  Should it be once the system has confirmed the cookie is valid, and thus change it at every successful logon?

 

And what purpose would i be serving by having an "expiration" field in the table?  would the cookie not have its own expiration? Would i be comparing the cookie's expiration value to that of the database?

 

Thanks for being patient - I'm learning quickly but I've got a long way to go.

um...you can keep it all in one table, but it's usually more efficient to keep the extra info in a second table.

 

once they submit their login credentials, and you validate who they are, if they have selected 'remember me', generate a random md5 hash, and put it in the 'remember me' table as i described before and put it as a cookie in their browser. you shouldn't need to keep re-generating each time they load a page...just when they do a formal login.

 

the expiration date in the table is needed because a user can alter cookies in their browser, including the date they expire.

I guess the last (and hopefully final) question on the subject is execution.

 

right now i'm envisioning

Create Cookie:
setcookie("logged_in", [uid]|[hash],time()+2592000); //30 days

 

then i'd check to make sure the values below (uid, hash) match the ones stored in the DB.

$thecookie = explode("|",$_COOKIE['logged_in']);
$thecookie['0']
$thecookie['1'];

 

Is that right?  Is there an easier way to store an array in a cookie, or is the recommended path to create multiple cookies: 1 for each stored value?

 

At this point I'm not 100% sure how to check the cookie to compare expiration but I'm sure I can figure it out eventually  ;)

 

Thanks again.

you can store arrays into cookies, but don't bother. you don't even need the uid in the cookie. to make the hash, use something like:

$hash = md5(microtime().getmypid());

that will give you a unique hash every time

 

so, to set the cookie would look like:

//at this point, their username/password have been verified 
//and their username or uid is stored into $uid
session_start();
$hash = md5(microtime().getmypid());
$expire = time()+2592000; //30 days
setcookie("logged_id",$hash,$expire,'/'); //the '/' makes the cookie available to the entire domain
mysql_query("INSERT INTO logged_ins (uid,hash,expiration) VALUES ('$uid','$hash','".date('Y-m-d',$expire)."')") or die(mysql_error());
$_SESSION['uid'] = $uid;

 

then on each page they need to be logged in, you use the following include:

<?php
  if($_SESSION['uid']){
    print "You are currently logged in as: ".$_SESSION['uid'];
  }elseif($_COOKIE['logged_in']){
    //First, let's clean up the table
    //This part could be moved to a cronjob if you want
    mysql_query("DELETE FROM logged_ins WHERE expiration <= NOW()") or die(mysql_error());
    //Now look for the hash
    $hash = mysql_real_escape_string($_COOKIE['logged_in']);
    $result = mysql_query("SELECT uid FROM logged_ins WHERE hash = '$hash' AND expiration <= NOW()") or die(mysql_error());
    if(mysql_num_rows($result) === 1){
      list($uid) = mysql_fetch_array($result);
      print "I remembered that you were logged in as: ".$uid;
      $_SESSION['uid'] = $uid;
    }
  }
  if(empty($uid)){
    //Not logged in
    header('Location: login.php');
    exit;
  }
?>

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.