Page 1 of 2
Session hijacking -- easy fix?
Posted: Thu Jul 28, 2005 11:25 am
by nielsene
I've been playing with various methods to make PHP generate "proper" session tokens for a while, something of the form sessionID,expTime,HMAC(sessionID,expTime) as a single value, etc. Most of my attempts got bogged down in little details and I went onto other tasks....
After
CoderGoblin's post this morning about
output-add-rewrite-var I got to thinking that this might be an easy way to help defend against session hijacking.
Here's the beginning of the idea...
Code: Select all
<?php
$sessionHash=SHA1($SERVER_SECRET.session_id());
if (!isset($_COOKIE["sessionHash"])) {
output-add-rewrite-var("sessionHash",$sessionHash);
} else {
setcookie( ... );
}
?>
at the top of every page and then rehash the return sessionid against the sessionhash. If they don't match, then its a session hijack attempt. If there's no corresponding hash, then its a session hijack attempt.
Its not a fleshed out system, but does it show promise?
jcart | fixed php tags for ya
Posted: Thu Jul 28, 2005 12:31 pm
by Ambush Commander
IMHO, I wouldn't use it because it's just not a good idea to put the session id inside the URLs.
Posted: Thu Jul 28, 2005 12:32 pm
by nielsene
Session IDs already get added to the URL if you reject the cookie...
So unless you've set user_only_cookie to 1 in the php.ini, this has to be a possible concern.
Posted: Thu Jul 28, 2005 12:41 pm
by Ambush Commander
Okay... I'm not exactly sure if I understand what you're doing...
We create a sessionHash based on the other session information (cookie/getstring). We pass that around the same way PHPSESSID is passed around. So now we've got "two" session identifiers. So... all the hacker has to do is steal both PHPSESSID and sessionHash cookies to hijack the session. Is that what you're doing? (In this case, output-add-rewrite-var is magical because it lets you more closely match sessionHash to PHPSESSID).
Re: Session hijacking -- easy fix?
Posted: Thu Jul 28, 2005 1:14 pm
by Roja
nielsene wrote:I've been playing with various methods to make PHP generate "proper" session tokens for a while
I'm a little puzzled by this comment.
A session token by itself has nothing to do with preventing session hijacking. I'm curious what you think a 'proper' session token consists of, and how it helps with hijacking.
nielsene wrote:something of the form sessionID,expTime,HMAC(sessionID,expTime) as a single value, etc.
Thats two items: Session ID (Already have it), and Exp time (Already set on the server side, and updated after each page).
By combining them (hmac) you ensure that either you cannot do a direct check from the last page (because the exp time will be based on the new page), OR, sessions wont update based on last movement. In both cases, its *less* useful and secure than the php session id.
What did I misundertand?
Posted: Thu Jul 28, 2005 1:39 pm
by nielsene
The session token is a form of an authenticator token. It is used to uniquely pair a given person with a server-side state. (Even if not logged in its still a form of authentication.)
Authenticator theory tends to require
1. the authenticator id
2. the expiration time of the authenticator
3. cyrptographic protection of both against tampering
Thus the normal
Code: Select all
$payload="e;$id+$expTime"e;;
$mac=HMAC($payload);
$message="e;$payload+$mac"e;;
('+'s used to avoid splicing attacks and ease "exploding", depending on your HMAC output, you might need to change component delimitator.)
The mac ensures that a user can't change either the id or the expTime associated with the token and that the token is basically atomic at the user level.
So this is more of a defense against session hijacking via guessing/morphing a known session id, than a sniffing/replay attack. Its possibly to avoid the replay attack vector by adding a nonce to the token; the sniffing one is not amenable to correction via this method. To close the sniffing vector, configure php to only use cookies for session and then only send cookies via SSL.
This method does help in a shared hosting environment where people can see the names of the temp session files, while they can "guess" the session id with 100% certainity, they don't have the hash so the session is invalid.
Most of my past work has been in coding up custom session handlers that automatically do all this in the regular session token, but I never quite finished it.
I'm not sure about your final paragraph, so I can't address that one. You can either reset the expTime on every page or choose not to set it again if a valid token exists, allowing the develop to choose from either absolute or relative expTimes.
Posted: Thu Jul 28, 2005 1:49 pm
by Ambush Commander
Hm... when you put it that way, it makes a lot more sense when you view a Session has an authentication token and then make it so that it emulates one.
But... does PHP have an HMAC function (checks docs, nope it doesn't)?
Posted: Thu Jul 28, 2005 1:51 pm
by nielsene
I've tend to code up my own, and I think I've seen some in the code snippets....
Posted: Thu Jul 28, 2005 2:26 pm
by Roja
nielsene wrote:The mac ensures that a user can't change either the id or the expTime associated with the token and that the token is basically atomic at the user level.
Right.
The php exptime can't be changed by the user at all - its handled server-side by php. Thats why id+exptime (hmac'd or not) is of no advantage over php's sessionid.
nielsene wrote:So this is more of a defense against session hijacking via guessing/morphing a known session id, than a sniffing/replay attack.
Thats definitely a different problem.
In PHP's session id, if the attacker guesses a good session id, he's still going to need a valid session variable - perhaps username - to match. If he doesn't, the application should reject him.
In your session id, its no different - if the attacker can get the session id, the exptime is simply another value he has to guess, much like the missing matching username from php's session id scenario above. Not to mention, by flooding the webserver, the attacker can get an extremely reliable/predictable exptime. From there, creating an hmac of it and the session id is trivial.
All told, it really doesn't hold much advantage.
nielsene wrote:Its possibly to avoid the replay attack vector by adding a nonce to the token
Its important to note that you are leaving out the key behavior that makes a nonce valuable - non-repeatability. The session id doesnt change. The exptime does, but you can retry (repeat) values over a period of time. If you couple that with flooding the server, you can get an extremely reliable exptime, which is your nonce. Thus, its not a proper nonce. A proper nonce 'locks out' repeated attempts of the same nonce.
nielsene wrote:To close the sniffing vector, configure php to only use cookies for session and then only send cookies via SSL.
Alternatively, you can use a solution that works regardless of SSL's presence: session regeneration, limited session times, and db-driven sessions.
nielsene wrote:
This method does help in a shared hosting environment where people can see the names of the temp session files, while they can "guess" the session id with 100% certainity, they don't have the hash so the session is invalid.
Read above about how to get a reliable ExpTime hash. Its not common, but it is used. DB-driven sessions on the other hand solve the shared hosting problem perfectly.
Posted: Thu Jul 28, 2005 2:49 pm
by nielsene
Roja wrote:nielsene wrote:The mac ensures that a user can't change either the id or the expTime associated with the token and that the token is basically atomic at the user level.
Right.
The php exptime can't be changed by the user at all - its handled server-side by php. Thats why id+exptime (hmac'd or not) is of no advantage over php's sessionid.
OK, well the main paper I'm basing some of this after was targetting cookie authenticators (remember me, style) their the expTime is not under server control. So yes, I'll agree you could drop the expTim here, but I'll still argue that the HMAC of the sessionID is valuable, below.
nielsene wrote:So this is more of a defense against session hijacking via guessing/morphing a known session id, than a sniffing/replay attack.
Thats definitely a different problem.
In PHP's session id, if the attacker guesses a good session id, he's still going to need a valid session variable - perhaps username - to match. If he doesn't, the application should reject him.
Hmm? If a user gets another user's session id, game over. There is nothing else to match. Unless you're sending a second cookie/GET based authenticator to compare against?
In your session id, its no different - if the attacker can get the session id, the exptime is simply another value he has to guess, much like the missing matching username from php's session id scenario above. Not to mention, by flooding the webserver, the attacker can get an extremely reliable/predictable exptime. From there, creating an hmac of it and the session id is trivial.
Incorrect. An HMAC is a secure hash, designed to detect tampering of the protected contents. And is constructed using a server secret. The attacker can not generate a hash of an arbitrary session id that will succeed.
nielsene wrote:Its possibly to avoid the replay attack vector by adding a nonce to the token
Its important to note that you are leaving out the key behavior that makes a nonce valuable - non-repeatability. The session id doesnt change. The exptime does, but you can retry (repeat) values over a period of time. If you couple that with flooding the server, you can get an extremely reliable exptime, which is your nonce. Thus, its not a proper nonce. A proper nonce 'locks out' repeated attempts of the same nonce.
I wasn't claiming that the expTime was a nonce, but I can see how it might have been unclear. I was saying if you wanted to further secure against the two threat vectors not already address, adding a nonce to the token would help.
nielsene wrote:To close the sniffing vector, configure php to only use cookies for session and then only send cookies via SSL.
Alternatively, you can use a solution that works regardless of SSL's presence: session regeneration, limited session times, and db-driven sessions.
Again, incorrect. Those merely narrow the temporal window for a sniffed attack. (Yes the DB one limits the shared host problem as well.) Session regeneration/limited session times can't distinguish a sniffed token from a valid token, even if using a nonce, as the attacker may submit before the user.
Posted: Thu Jul 28, 2005 4:14 pm
by Roja
nielsene wrote:Hmm? If a user gets another user's session id, game over. There is nothing else to match. Unless you're sending a second cookie/GET based authenticator to compare against?
I usually suggest to do so, yes.
nielsene wrote:
Incorrect. An HMAC is a secure hash, designed to detect tampering of the protected contents.
Not the way you are using it isn't. An HMAC is only secure when the contents of the secret aren't known. Since the attacker knows one of the secrets, and can guess the other one, the HMAC becomes a plain hash - not secure. Its repeatable on both sides.
nielsene wrote:And is constructed using a server secret. The attacker can not generate a hash of an arbitrary session id that will succeed.
You said: HMAC(sessionID,expTime).
Thats not a server secret, and yes, the attacker can generate that same HMAC, so no, its not secure.
nielsene wrote:Roja wrote:Alternatively, you can use a solution that works regardless of SSL's presence: session regeneration, limited session times, and db-driven sessions.
Again, incorrect. Those merely narrow the temporal window for a sniffed attack. (Yes the DB one limits the shared host problem as well.) Session regeneration/limited session times can't distinguish a sniffed token from a valid token, even if using a nonce, as the attacker may submit before the user.
"Narrowing the window" is accurate, but also understating the value. The window may be impossibly small. For example, if I do a session regeneration upon login, and you sniff my session immediately before, we might be talking about a window in miliseconds.
As to detecting a sniffed session, if SSL is unavailable, I'm not aware of a definitive prevention - just ways to limit the impact.
Posted: Thu Jul 28, 2005 5:06 pm
by theda
My question for you all is simple:
What the hell use is all of this...? You're websites are probably not big enough to experience hacking, unless you are contracted to do a large job, like a game server, or a secure transaction server... I don't see the use
And here's a little philosophy: If you don't want something found out, don't have it exist in the first place. If it exists, then there also exists more than one way to get it

Posted: Thu Jul 28, 2005 5:08 pm
by Ambush Commander
Security by Obscurity is not the answer!
The reason we do this is because there are people who will find your site and think it's funny to hack it.
Posted: Thu Jul 28, 2005 5:12 pm
by Roja
theda wrote:What the hell use is all of this...? You're websites are probably not big enough to experience hacking, unless you are contracted to do a large job, like a game server, or a secure transaction server... I don't see the use

Well, I code multiple opensource games - including games that have over 100,000 users which get hacked *daily*. Sometimes detected, sometimes not.
In addition, I reuse my code in other projects, which drive even larger sites. I work in Information Security, so security is a passion for me.
All of these things make it very useful for me. Your useful is hopefully very different from my useful.

Posted: Thu Jul 28, 2005 5:23 pm
by John Cartwright
theda wrote:My question for you all is simple:
What the hell use is all of this...? You're websites are probably not big enough to experience hacking, unless you are contracted to do a large job, like a game server, or a secure transaction server... I don't see the use
And here's a little philosophy: If you don't want something found out, don't have it exist in the first place. If it exists, then there also exists more than one way to get it

Speak for yourself there Theda, these discussions are invaluable to several members of these boards. I am developing how you put "a secure transaction server" and have learned a lot over the years through such readings and alike.