4

Thanks for your replies. I have updated my PHP session code.

I have got rid of the user agent check as @Rook has shown me the flaws in the logic.

Unfortunetly I messed up the original question by editing it now I cant get it back sorry guys but @Rook did solve the original question I had.

Thanks again for your help guys, daza166

daza166
  • 3,543
  • 10
  • 35
  • 41

3 Answers3

6

Nothing that you are doing is really improving the strength of a session. You have to be clear about what attack you are defending against because your checks do not prevent attack. A good example is checking the user-agent which is trivial to spoof. Rolling the session id, doesn't help if even one value is leaked or you have an XSS/CSRF vulnerability then the attacker has control of the session.

Read OWASP A3-Broken Authentication and Session Management. Also read about OWASP A5-CSRF, which is sometimes called "session riding".

You should use this code in a php header file:

ini_set('session.cookie_secure',1);
ini_set('session.cookie_httponly',1);
ini_set('session.use_only_cookies',1);
session_start();

This code prevents session fixation. It also helps protect against xss from access document.cookie which is one way that Session Hijacking can occur. Enforcing HTTPS only cookies is a good way of addressing OWASP A9-Insufficient Transport Layer Protection. This way of using HTTPS is sometimes called "secure cookies", which is a terrible name for it. Also STS is a very cool security feature, but not all browsers support it (yet).

rook
  • 66,304
  • 38
  • 162
  • 239
  • Ok thats a fair point Rook I see what you mean I am just making the hacker re-login again, so what exactly do you suggest I do within the if($_SESSION['uagent'] != $browser_check) or is there anything I can do to overcome this problem? After all thats the bit where I am trying to catch out a potential hacker from a session hijack. – daza166 May 01 '11 at 22:08
  • @user535256 I would never check any attacker controlled variable for security. Instead you should focus on serious vulnerabilities like OWASP a9, make sure you use ssl for the life of the session. Also "session riding" aka CSRF, "session fixation" and xss. This is the best way to improve PHP's session handler: (http://stackoverflow.com/questions/3517350/session-hijacking-and-php/3517616#3517616) – rook May 02 '11 at 00:54
  • @Rook, you make interesting points I would never thought of thanks. So let me make sure I understand you, that ini_set()'s will set a secure cookie (meaning the browser will only transmit it over an SSL link) and I need this included on every php page. Should I put this into php.ini rather than php header file? Does that mean once the user logs in once I need all the pages to be SSL even when he clicks on a non-sensitive page whilst logged in ie about-us? Is there any way to do this without having to have SSL on non-sensitive pages or would I have to redirect them to SSL page of the about-us? – daza166 May 02 '11 at 13:05
  • @Rook, When should I regenerate session_ids then or is there any need? "A hijacking user will try to set his session ID prior to login this can be prevented if you regenerate the ID at login" and chris shifflet article mentions about the user agent checks - http://shiflett.org/articles/the-truth-about-sessions. Surely the user agent check would be worth including as well as points you mentioned as a user agent changing in middle of session would be suspicious (I know compatibility mode in ie messes this up) but still would this not be Defense in Depth on top of what you have mentioned? – daza166 May 02 '11 at 13:08
  • @daza166 yeah you can add these configurations into the php.ini. At no point can the session id be transmitted over http. So if you issue a session and they login and you want to switch to https, then regenerate the session id and set the https only flag on the cookie (cookie_secure). All requests will have the session id, which means **ALL** requests are sensitive. Once an attacker has the session id, its game over. You have to keep that from happening. The session id is the authentication token, it is how you know a browser is logged in. – rook May 02 '11 at 16:46
  • @daza166 Chris is a good hacker. But I could not disagree more with that article, its pure secuirty though obscurity and he doesn't even talk about cookie flags. – rook May 02 '11 at 17:00
  • @Rook - I have added the ini_set's into my php.ini file. I have got rid of my user agent test as you have explained its flaws very well. However now my only problem lies with the session between HTTPS and HTTP and back to HTTPS. NOTE I edited my original question to this thread to explain what I mean, thanks! – daza166 May 02 '11 at 20:52
  • @daza166 I think that's a different question. You should award this one and post a new one. I think you'll get better answers, and mine might not be your favorite. – rook May 02 '11 at 20:54
  • @Rook, Ok well thanks very much for your help, you get best answer. – daza166 May 02 '11 at 20:59
4

If a logged-in user does not log out of his account and the session thus never gets destroyed ie (logout-page.php), would the session die when the browser closes? Reason I ask is if the user does not log out when browser closed, when browser re-opened, the site says user is still logged in.

No. The session is managed on the server side and the client does only get the session ID for identification. Closing the browser would only destroy session cookies (i.e. cookies that is only valid during the current browser session) that hold the session IDs but not the associated sessions. If the same session is used after re-opening the browser, the session’s cookie is probably not a real session cookie but a persistent cookie. You can adjust that setting session.cookie_lifetime to 0.

Is it best to keep the user logged in (ie login.php - enter details once->start session) rather then requiring user to keep logging in, as mentioned if an error occurs on my scripts or if certain pages user accesses I destroy the session (ie log them out)?

In general, as you use the session for a user authentication purpose, you should only demand for re-authentication if you have doubts about the current user’s authentication (e.g. user agent changed) or if you want an additional authentication confirmation (e.g. privilege changes, as evidence for non-repudiation, etc.).

Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • thanks gumbo, would http to https (vice versa) be a privilege change? I will change session.cookie_lifetime=0 in php.ini should stop the persistence cookie. BTW the session is not just for authentication but I store variables in session ie email add, advert ref, user id etc but that is still authentication I guess but as long as I check the format of these $_SESSION varaiables I should be secure as can be right? ie if user id $_SESSION var is not say 7 digit its been tampered. – daza166 May 01 '11 at 14:22
  • @user535256: No, it wouldn’t be a change of privilege but it would probably be a change of confidentiality. And in that case it would make sense to re-authenticate the user. – Gumbo May 01 '11 at 17:24
  • after reading into sessions, sadly there is nothing much I can do. Your method of using user agent check is just checking session to session which is trivial to spoof. IP to IP is unreliable, so is there point of doing either? Hashing/salting user agent $_SESSION is pointless I believe too. So is it best to perform these checks or not? I have SSL(secure cookie) and as long as I just regenerate id on login/when privilege change and after 5 mins would that be sufficient protection? User agent/IP checks are they worth doing even for defense in depth although hacker can spoof these easily? – daza166 May 02 '11 at 13:50
  • @daza166: Like [@Rook had written in his first revision](http://stackoverflow.com/revisions/6f1b00b0-e0e2-4627-9fc1-1407449c0188/view-source), checking the user agent is not reliable as it can also be tampered. But it does’n hurt to check that as well. Checking the IP address is differently as the IP address can change during the session (even with every request). – Gumbo May 02 '11 at 15:00
2

Seems like a reasonable question to me :)

Anyways, you're already on a pretty good track with regenerating the ID for safety reasons. It does help prevent session hijacking.

You can use session_set_cookie_params to set the session ID cookie's lifetime. This should be what you need for #1

As for #2, I haven't actually ran into apps that would destroy the session when an error occurs, but I suppose it could be a good idea at least if your application throws an error because of a programming bug or the user attempting to do something they shouldn't. You might want to implement some sort of error logging and alerting for this so you can fix the stuff.

Jani Hartikainen
  • 42,745
  • 10
  • 68
  • 86
  • -1 regenerating the session id does not prevent session hijacking. An attacker payload could be pure javascript and ride on the session to perform any action. – rook May 02 '11 at 01:44
  • That has nothing to do with session hijacking – Jani Hartikainen May 02 '11 at 01:48
  • @Jani Hartikainen JS is very useful for hijacking sessions just look at the Sammy worm. Even if the attacker used a browser a `session_regenerate_id()` will update his cookie. – rook May 02 '11 at 02:03
  • The samy worm was an XSS/CSRF exploit... and has absolutely nothing to do with session hijacking :) – Jani Hartikainen May 02 '11 at 02:26
  • @jani-hartikainen, conflicting opinion with Rook. Method of using user agent check is just checking session to session which is trivial to spoof. IP to IP is unreliable, so is there point of doing either? Hashing/salting user agent $_SESSION is pointless I believe too. So is it best to perform these checks or not? I have SSL(secure cookie) and as long as I just regenerate id on login/when privilege change and after 5 mins would that be sufficient protection? User agent/IP checks are they worth doing even for defense in depth although hacker can spoof these easily? – daza166 May 02 '11 at 13:55
  • @Jani Hartikainen sammy wasn't csrf because MySpace had protection in place. He used XSS to read the csrf token and then make the request. The only vulnerability that was patched was stored xss. To be honest i don't care what you call it, its insecure and that's all that matters. – rook May 02 '11 at 17:39
  • @Rook the point was that you -1'd because of a misunderstanding :) @daza166 Regenerating the ID will help prevent session fixation and thus prevent session hijacking. Using a combination hash of UA+IP+secret token can also help against session hijacking because the entire combo is harder to get right – Jani Hartikainen May 02 '11 at 19:15
  • @Jani Hartikainen Your aren't preventing session fixation, you are making the window smaller. Where as by adding the line: `ini_set('session.use_only_cookies',1);` then you 100% stop session fixation. This is the real solution using the platform, not some cracked out home brew patch. – rook May 02 '11 at 19:24
  • @Rook Incorrect. If the session cookie leaks out (f.ex. via XSS and document.cookie), it's still quite vulnerable. Regenerating the ID will help reduce the likelihood of this allowing a hijack - but yeah, it might be smart to regenerate it more often if you really want to secure it. – Jani Hartikainen May 02 '11 at 20:58
  • @Jani Hartikaine Yes, and `session.cookie_httponly` makes it so that javascript cannot access `document.cookie` and `session.cookie_secure` makes it so that the cookie is only transmitted over https (to thwart firesheep sytle attacks). Maybe you should just read my post. – rook May 02 '11 at 21:05
  • I didn't even notice you had posted something since I was just checking back to reply :D Anyways yeah, using the combination works. – Jani Hartikainen May 02 '11 at 21:09