Session security!

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Recoil UK
Forum Newbie
Posts: 23
Joined: Sat Jul 12, 2003 5:59 pm

Session security!

Post by Recoil UK »

Hi guys

Thought I would start this thread, just to gauge everybodys opinion on session security and how to implement it.

My own personal view, is that you need a custom session handler that stores information in a database, what u think?

Now as to what information should be stored in this database, well, I think the following.....

session_id
encrypted ip
expiration time
session $vars

But I dont see that its enough.

What are your thoughts?

L8rs
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

It depends. Why do you feel the basic file based session approach is insecure? Are you on a shared host/server? Do you have untrusted local users, etc?

Its hard to say whether you need costume session handlers or not without knowing what your environment is, and what level of security you are trying to provide.
Recoil UK
Forum Newbie
Posts: 23
Joined: Sat Jul 12, 2003 5:59 pm

Post by Recoil UK »

Hi

Well yeah, I will be on a shared host to start with, which is one of the reasons, the other being, that not only has someone got to hack the server, but they also have to hack the database. This has to be more secure than using file based sessions in a temp dir somewhere.

I,m more interested in what methods people use to implement user/logins etc, what else is needed to be added to the list.

Thx
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

Yes, so in a shared host environment you probably need to move to some custom sessions handler. Of course a custon file base approach may also be posible and still be secure. Hacking a DB is normally fairly trivial is they've already hacked your box, as normally your DB passwords are stored on the box....

As to what information is important to track. I would say SessionID, UserID, IP, and expiration time should all be tracked to uniquely identify the session. Then store a MAC of all the above to protect against tampering.

Logins are a seperate issue and there are several examples if you search in this form, or read the tutorials at the phpComplete site.
Recoil UK
Forum Newbie
Posts: 23
Joined: Sat Jul 12, 2003 5:59 pm

Post by Recoil UK »

Hi

Thx for the reply.

Here,s what I have so far.

http://www.phpbuilder.com/columns/ying2 ... hp3?page=1

Code: Select all

<?

$SESS_DBHOST = "localhost";			/* database server hostname */
$SESS_DBNAME = "dbname";			/* database name */
$SESS_DBUSER = "dbuser";		/* database user */
$SESS_DBPASS = "password";		/* database password */

$SESS_DBH = "";
$SESS_LIFE = get_cfg_var("session.gc_maxlifetime");

function sess_open($save_path, $session_name) {
	global $SESS_DBHOST, $SESS_DBNAME, $SESS_DBUSER, $SESS_DBPASS, $SESS_DBH;

	if (! $SESS_DBH = mysql_connect($SESS_DBHOST, $SESS_DBUSER, $SESS_DBPASS)) {
		echo "<li>Can't connect to $SESS_DBHOST as $SESS_DBUSER";
		echo "<li>MySQL Error: ", mysql_error();
		die;
	}

	if (! mysql_select_db($SESS_DBNAME, $SESS_DBH)) {
		echo "<li>Unable to select database $SESS_DBNAME";
		die;
	}

	return true;
}

function sess_close() {
	return true;
}

function sess_read($key) {
	global $SESS_DBH, $SESS_LIFE;

	$qry = "SELECT value FROM sessions WHERE sessionid = '$key' AND expirytime > " . time();
	$qid = mysql_query($qry, $SESS_DBH);

	if (list($value) = mysql_fetch_row($qid)) {
		return $value;
	}

	return false;
}

function sess_write($key, $val) {
	global $SESS_DBH, $SESS_LIFE;

	$expirytime = time() + $SESS_LIFE;
	$value = addslashes($val);

	$qry = "INSERT INTO sessions VALUES ('$key', $expirytime, '$value')";
	$qid = mysql_query($qry, $SESS_DBH);

	if (! $qid) {
		$qry = "UPDATE sessions SET expirytime = $expiry, value = '$value' WHERE sessionid = '$key' AND expirytime > " . time();
		$qid = mysql_query($qry, $SESS_DBH);
	}

	return $qid;
}

function sess_destroy($key) {
	global $SESS_DBH;

	$qry = "DELETE FROM sessions WHERE sessionid = '$key'";
	$qid = mysql_query($qry, $SESS_DBH);

	return $qid;
}

function sess_gc($maxlifetime) {
	global $SESS_DBH;

	$qry = "DELETE FROM sessions WHERE expirytime < " . time();
	$qid = mysql_query($qry, $SESS_DBH);

	return mysql_affected_rows($SESS_DBH);
}

session_set_save_handler(
	"sess_open",
	"sess_close",
	"sess_read",
	"sess_write",
	"sess_destroy",
	"sess_gc");
?>
At the moment its only using a 3 column database table and I think I understand what most of it does.

sessionid
expirytime
value

I plan to add the following 2 columns

userid
userip

and also a MAC when I discover what the hell it is :)

I also have to close my database calls in sess_close() as i,m not using pconnects as the tutorial suggests.

So whats a MAC???

Thx
User avatar
redhair
Forum Contributor
Posts: 300
Joined: Fri May 30, 2003 4:36 pm
Location: 53.23N-6.57E
Contact:

Post by redhair »

A MAC is a unique(!) number on a network card.
User avatar
redhair
Forum Contributor
Posts: 300
Joined: Fri May 30, 2003 4:36 pm
Location: 53.23N-6.57E
Contact:

Post by redhair »

Wich remindes me....
Can a MAC number be retreived at all?
I had one teacher of mine said it could'nt...(via TCP-IP)
I'm still curious...is that really true?
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

Actually I was talking about a "Message Authentication Code" not the network address.

Normally produced by doing calculating a one-way hash over the message and a server side secret. The simplest way in PHP would be

$mac = MD5($stuff_to_protect . $SERVER_SECRET);

Then when on each new page view you recompute the mac and compare it to the stored value. If they don't match then you know someone is tampering with your session.
User avatar
redhair
Forum Contributor
Posts: 300
Joined: Fri May 30, 2003 4:36 pm
Location: 53.23N-6.57E
Contact:

Post by redhair »

Ah.. ok :oops:
Recoil UK
Forum Newbie
Posts: 23
Joined: Sat Jul 12, 2003 5:59 pm

Post by Recoil UK »

Hi guys

Is it really that easy to modify a session cookie? after all they arent like normal cookies stored in a file, they are only held in memory for the lifespan of the browser window.

If they are, is it still possible to use the MAC method?

Thx
Recoil UK
Forum Newbie
Posts: 23
Joined: Sat Jul 12, 2003 5:59 pm

Post by Recoil UK »

Hi again

Got another question.

Does PHP use MD5 when it creates the session id? or something else.

Its just that i,m testing on windows xp, and not sure how to install MD5.

L8rs
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

Recoil UK wrote:Hi guys

Is it really that easy to modify a session cookie? after all they arent like normal cookies stored in a file, they are only held in memory for the lifespan of the browser window.

If they are, is it still possible to use the MAC method?

Thx
Session cookies are, by default, ephemeral. Meaning that they are only stored for the life of the browser or the their expiration time, whichever comes first. However, all cookies are trivial to edit should the user choose to, hence my suggestion to MAC the cookie.

I don't beleive PHP uses MD5 when creating the sessionid. MD5 however should be installed without you having to do anything, I think? I've never had to do anything special to get it, at least....
Recoil UK
Forum Newbie
Posts: 23
Joined: Sat Jul 12, 2003 5:59 pm

Post by Recoil UK »

Hi again

But the only thing in a session cookie is the sessen id, and as thats allready a unique value, whats the point.

I can see why you would want to use a MAC on a normal cookie, just not a session cookie.

L8rs
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

Recoil UK wrote:Hi again

But the only thing in a session cookie is the sessen id, and as thats allready a unique value, whats the point.

I can see why you would want to use a MAC on a normal cookie, just not a session cookie.

L8rs
Because if the user can simply update/change the sessionid they may be able to "hijack" another user's session, therby assuming their permissions and identity. MAC-ing the session ID makes it very easy to detect this mode of attack.
penny
Forum Newbie
Posts: 3
Joined: Tue Jul 15, 2003 8:53 am

Post by penny »

nielsene wrote:
Recoil UK wrote:Hi again

But the only thing in a session cookie is the sessen id, and as thats allready a unique value, whats the point.

I can see why you would want to use a MAC on a normal cookie, just not a session cookie.

L8rs
Because if the user can simply update/change the sessionid they may be able to "hijack" another user's session, therby assuming their permissions and identity. MAC-ing the session ID makes it very easy to detect this mode of attack.
can't see how would you like to prevent hijacking of a sessionid with MACing? if someone can use others sessionid, and you MAC it to check if it's correct, then you still get corret value! 'cause sessionid is correct, and $SERVER_SECRET is constant (or at least always the sam for one sessionid). The only values you could MAC to get level of sevurity you write of is MACing IP and sessionid BUT there are methods that allow hacker's computer to identify itself with others IP adresess.

So if someone will REALY WANT to hack into someone's session it won't be imposible for him. AND if he want's it so badly that he steals others sessionids, using fake IP wouldn't be a problem for him

Penny
Post Reply