2

I was doing some research on StackOverflow on how to properly set sessions and prevent hijacking, etc. I found an answer that someone posted on one of the questions and he provided the following code:

For when a user logs in and the username and password match

$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] .''. $_SERVER['REMOTE_ADDR']);

Checking if user is logged in, for protected pages:

if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] .''. $_SERVER['REMOTE_ADDR'])) {       
        session_destroy();
        header('Location: login.php');
        exit();     
    }

It seems to work fine, but my questions are: how secure is this, is this a good method or should I try something else? The post had no upvotes or anything so not sure if it's good.

Also, not sure how to get information about a user with this session .. do I need to store anything in the database?

Thank you!

Gumbo
  • 643,351
  • 109
  • 780
  • 844
Drew
  • 6,736
  • 17
  • 64
  • 96
  • Using IP address has it's own issues. Dynamic IPs can often change. If you need a secure solutions then I think it's better to use HTTPS. – Karolis Aug 21 '11 at 17:32

3 Answers3

3

There are two major problems with this code.

1) IP addresses change for legitimate reasons. If the client is behind a load balancer, like at a corporate network, then he will be unable to use your web app.

2) Checking the user agent is a lot like having a get variable that says ?is_hacker=false. If the hacker has the session id, he has the user agent and its trivial to spoof.

Further more i have no idea why you would want to use md5 for this when doing a plain text comparison is actually more secure. Because the user agent is first an attacker could use the md5 prefixing attack to produce a collision and there for would bypass the REMOTE_ADDR check. (A useful md5 collision attack doesn't come up too often, but this one is fun!)

Even with this check in place CSRF and XSS can still be used to influence the session. XSS can be used to read a CSRF token and then use XHR to make any request the attacker desires. One could make the argument that this is trying to mitigate OWASP a9, but really you need to be using SSL to protect the session id.

rook
  • 66,304
  • 38
  • 162
  • 239
  • 1
    The latter item is not necessarily true: The session ID might have been obtained from a URL that the victim published somewhere without the user agent ID. And CSRF attacks are not dependent on sessions, they can also occur on other authentication techniques. – Gumbo Aug 21 '11 at 17:40
  • @Gumbo♦ for one he is using a $_SESSION, so there is a session id somewhere. By default php uses cookie for sessoin id's, but there is no guarantee he is using the defaults. That aside, the user agent is also easier to brute force than a password. If its chrome, then it will always be the latest version, ect. – rook Aug 21 '11 at 17:48
  • @Gumbo♦ Also on a side note, i was talking to the customer service of a major US company and they printed out some information for me. At the bottom of the page was the URL because it was printed from a browser, this included the jsessionid. Talk about a bad application design. – rook Aug 21 '11 at 17:51
  • You’re saying that “if the hacker has the session id, he has the user agent”. And that’s wrong. Because you can’t reason the user agent ID from a session ID, what your statement implies. – Gumbo Aug 21 '11 at 18:11
  • @Gumbo♦ I'm sorry I still stand by my statement, it doesn't do shit for security unless your application has other more serious problems. – rook Aug 21 '11 at 18:12
  • I concur with your statement, that many don’t handle the session ID the way it should be handled. And it’s also true that some attacks to obtain a valid session ID do also unveil the user agent ID. And as the IP address indeed is not suitable as it might change during the session, the fingerprint would not prevent an attack (although it would decrease the possibility). But yet, reasoning the user agent ID from the session ID is still not possible (at least not with PHP’s default session ID generator). – Gumbo Aug 21 '11 at 20:48
0

I agree with Rook's comments, it's a pretty good analysis of your code.

There's lots to consider for securing PHP sessions but with an up to date version of PHP it's not difficult to achieve, some things to think about: - Where the session files are stored on your server (mainly an issue if it's a shared server) - Using a secure connection for all sensitive data and cookies going between the client & server - Doing what you can to make the cookie session ID on the client secure - Not storing any sensitive data in a session variable

As for storing things in a database it depends on your needs but I'd say you probably don't need it and storing data in the session variable is fine for security, just (as I've already stated) don't store anything sensitive there. Retrieve sensitive data from another location, most likely a database.

If you need to know more about PHP session security I've got a series of blog posts on the subject.

Neil Nand
  • 549
  • 6
  • 25
0

This looks like a good method, however the fingerprint hash is generated by client data, which can be spoofed. A good method to use for the login form is to generate a random token that is stored in the session and passed through the form. Once the token is validated (or not) it should be unset for a one time use only.

The session should also store the user id once the user is logged in to retreive the user info stored in the databse.

mgraphic
  • 48
  • 4
  • You are talking about a common method of CSRF protection. You are comparing apples and oranges. – rook Aug 21 '11 at 17:52