10

I have been working on a secure login/portal type set of tools, the general code is free from SQL injections, XSS etc, I have mulitple things in place to stop session hijacking.

  1. regenerate session's ID for EVERY page
  2. Compare the user's IP with the IP at login
  3. compare the user's user_agent with the agent at login
  4. have short session time outs

etc

I have done all I can think of to stop hijacking, however I have still located a situation where it might be possible and would like to know if anyone has any ideas.

Imagine a situation where you have 2 users behind a firewall which does SNAT/DNAT, so both apart to come from the same IP. They are both identical machines supplied by the same place. One connects to the site and logs in, the other copies the PHPSESSID cookie and can simply steal the session.

This might sound like an extreme example, however this is very similar to my place of work, everyone is behind a firewall so looks to be the same IP, and all machines are managed/supplied by the IT team, so all have the same version of browser, OS etc etc.

I am trying to think of another way (server side) to stop the hijacking or minimize it further, I was thinking of a token which gets embedded into every URL (changed for each page), and checked.

I am looking for ideas or suggestions, if you want to offer code or examples you're welcome, but I am more interested in out of the box ideas or comments on my token idea.

Marcel Korpel
  • 20,899
  • 5
  • 58
  • 79
Wolf
  • 101
  • 4
  • Based on your comment on @Artefacto's answer, it sounds like you're assuming the malicious attacker can simply copy the session cookies directly from the victim's filesystem... If that's the case, I'd say the problem is beyond your reach. – grossvogel Aug 29 '10 at 00:11
  • This is exactly the issue I am talking about and the only thing left I can think of I havent been able to programmatically solve. – Wolf Aug 29 '10 at 09:39
  • I know it is an extreme case, but i like to take things as far as possible with secure programming :) – Wolf Aug 29 '10 at 09:40

4 Answers4

3

Force everything to use HTTPS.

I think you are referring to a passive attack where a user in the network sniffs the cookie. For that, you don't need HTTPS. There are several options that are sufficient when the parties are sure to whom they're talking (e.g. you could do a DH exchange first and the server would encrypt a token the client would use in the next request...), but it's not worth the trouble going down that route.

If the user initially types in a non-https address, an active attack is still possible, but there's nothing you can do in that case. In the future, you might prevent future attacks of this kind once the user establishes one unadulterated connection to your site through HTTP strict transport security..

Marcel Korpel
  • 20,899
  • 5
  • 58
  • 79
Artefacto
  • 90,634
  • 15
  • 187
  • 215
  • https wont stop the issue I am taking about. If the person has your sessionid and appears to come from the same IP and user agent etc (anything else you can check in PHP), they can still assume your session. – Wolf Aug 28 '10 at 23:04
  • 2
    @Wolf If you're using HTTPS, no one else will be able to have your session id. No magical token is going to save you. You'd have to encrypt it, and even then it won't help in the case an active attacker is able to appear to the victim as if it were the real http server (e.g. through dns poisoning). Forget whatever tricks you're considering; they won't work. – Artefacto Aug 28 '10 at 23:10
  • See the comment above @Artefacto, this isnt an issue of snopping on the wire. – Wolf Aug 29 '10 at 09:39
  • 1
    @Wolf - *If* an attacker has your sessionid, it is game over. The point is, if you use https throughout, the attacker cannot get hold of the sessionid. – Sripathi Krishnan Aug 29 '10 at 12:40
  • @sri yeah i have to agree with the game over part. I cant see anything to stop that. But https, that doesnt protect the sessid cookie on the users machine as far as i am aware ?? – Wolf Aug 29 '10 at 13:52
  • I am guessing at the end of the day, if someone can take the cookie from your machine and spoof your IP / user-agent etc, then it really is game over as programatically speaking they are you, so I think I might have to call it a day as I think I have gone as far as I can using normal web programming. The only thing I could think of doing more is to have an app which gets installed locally in each machine which becomes part of the checking, but thats a little OTT and most people wouldnt install it. So thanks to everyone who has commented it has helped me draw a line on this one :) – Wolf Aug 29 '10 at 13:53
1

I wrote the main login portal for a major branch of the U.S. military.

I did all you mentioned above, plus at least one more step:

Have you stored a cookie on first login w/ the SESSION salt? Then encrypt everything serverside using that salt. The crooks would have to know about THAT cookie and STEAL IT, and it dramatically reduces exposure to session hijacking, as they just aren't lokoing for it.

Also, use JS and AJAX to detect if they have flash installed and if they do, store a flash cookie, too, with another salt. At that point you can more or less assume you have some pretty dedicated attackers out there and there's not much more you can do (like sending your users GPG keys to use via javascript and make them sign every single bit of data they send to you).

Theodore R. Smith
  • 18,715
  • 12
  • 52
  • 81
  • Hi this is an interesting idea, tell me more about the session salt cookie idea, is that a session cookie ?? I dont want to get into data signing and it starts to make the tool unuseable. I have extended to the code now to have a nonce built into every page, so that even if you steal the session cookie from the users browers, you dont have the nonce and so the first page you try to navigate to, fails and throw you to the login page after destroying your session. – Wolf Aug 31 '10 at 20:16
  • The nonce is sent into the page as a hidden field in a form, and I am using HMACs for all forms so the data cannot be changed. The only way I can see now for someone to hijack is to physically copy a cookie from someones machine that is logged in, spoof the IP, OS, user agent, and a form post over SSL/HTTPS, all in 15 mins as the user sessions auto timeout in 15 mins. ontop of that the sessionid is re-gen'd on every page load, so you have to take the cookie from someone logged in an inactive. – Wolf Aug 31 '10 at 20:16
  • beyond that I am not sure what else i can do, but the cookie idea you mention is of interest can you let me know more :) btw I will release the code and full security model details later this week :) when i finish playing with it :) – Wolf Aug 31 '10 at 20:16
0

Do not reinvent the wheal, the built in session handler for your platform is very secure.

There are a number of configuration for PHP's session handler. Use HTTPS, at no point can a session ID be transmitted over http "cookie_secure" does this, its a great feature but a terrible name. httponly cookies makes xss harder because javascript cannot access document.cookie. Use_only_cookies stops session fixation, because an attacker cannot influence this value on another domain (unless he has xss, but thats a moot point).

PHP configuration:

session.cookie_httponly=on
session.cookie_secure=on
session.use_only_cookies=on 
rook
  • 62,960
  • 36
  • 149
  • 231
-1

I am trying to think of another way (server side) to stop the hijacking or minimize it further, I was thinking of a token which gets embedded into every URL (changed for each page), and checked.

You should look at:

Understanding the Rails Authenticity Token

Tokens are a good idea.

Community
  • 1
  • 1
MrHus
  • 30,252
  • 6
  • 28
  • 31
  • 2
    Nothing to do with the question. That's a CSRF protection. – Artefacto Aug 28 '10 at 22:50
  • Hi, yeah this is the route I have been thinking of, something along the lines of tokens or nounces. The main idea is to keep something server side which is verified on EVERY page click and generated on every page load, this means having the sessionid wont help, because even going to the same URL will fail as the nounce should have changed – Wolf Aug 28 '10 at 23:03