3

Session Hijacking

So I have a slight problem. I'm trying to identify a visitor, which is very hard if not impossible by $_SERVER veriables as mentioned in this question: Preventing session hijacking.

Possible Solution

To make a bit harder than just copying the cookie from Client A to Client B (which is sadly childsplay), I want to collect some info and validate this against something I have stored. In my database I want to store things like User-Agent, IP-Address, OS etc. This I will encrypt using MCRYPT and store. To match against a user, a lot of variables have to be set, this makes it somewhat harder than just copying the cookie contents to login.

The problem

Here's when my problem starts... The User-Agent and OS are nearly if not completely identical. The reason is that it are Fat Clients with the same bootable image. Another problem is the IP. The server in the Datacenter has a connection to the office. For our applications (even tho not externally accessible) the IP-Address is the same for every client. I found out that I could try to use the X-Forwarded-For header to distinguish IP addresses and thus make the user a bit more unique.

What's next?

What I would like to know is the following: How can I make sure the X-Forwarded-For is ALWAYS set without having to anything the clients have access to? Does something have to be added there by routing? Our connection is https, so I doubt I can just "inject" something. Next to that, if I can inject something like this, can the users client side do this?

The clients are in our internal office network and the applications (running in php) are not accessible from the outside

Machavity
  • 30,841
  • 27
  • 92
  • 100
Anyone
  • 2,814
  • 1
  • 22
  • 27
  • 1
    In your internal network, you yourself (or the network admins) should be responsible for whatever part in the chain (some kind of proxy?) is setting the `X-Forwared-For` header. If the user has enough control over the client however, they might be able to set that header themselves. Btw., if you are talking about someone _deliberately_ passing on their session cookie to someone else, I would not call that session “hijacking”. So I’m not completely sure against what scenario exactly you are trying to secure your application here … – CBroe Jan 25 '14 at 19:27
  • It's just to make sure that the SSO system cannot be abused too easily due to bugs in our own code. You never know what they do, mailing document.cookie to them self for example... I wont prevent (too much hassle) stealing cookies of 1 application, but stealing that which gives access to all is just not cool :P – Anyone Jan 25 '14 at 19:49

1 Answers1

2

The X-Forwarded-For and User-Agent HTTP headers can easily be spoofed by any user (just as easily as copying a cookie from one machine to another).

Chrome extensions such as Header Hacker can be used on the client, and since your site is using HTTPS these headers cannot be added en route (as the headers need to added to the OSI application layer, not the transport layer).

If you're worried about users copying cookies between one another, is there any mechanism that would stop them sharing their username and password credentials? If you did manage to implement something that verified that their sessions remained on the same client machine, couldn't they simply work round it by logging in as each other?

Aside from my questions, for a solution you could introduce a local proxy into your internal network, purely for connecting to your site at the data centre. The site should reject any connections that are not from the IP of the proxy server (configure the web server or firewall to only accept the client IP of the proxy for web connections). Using this approach you will need to install an SSL certificate onto the proxy, which each client machine can trust. This will enable the proxy server to decrypt traffic, add the appropriate IP address header (overwriting any set by the client) and then forward it onto your server. The server code can then safely check the X-Forwarded-For header to make sure it remains constant per user session.

If this sounds like a good solution, please comment if you have any questions and I'll update my answer.

Two other thoughts:

  • You could use something to fingerprint the browser like panopticlick. However, as this is retrieving various values from the client and creating a fingerprint, it can all be spoofed if the headers are set the same as another user's. Also, as each machine is from the same bootable image, this might well be the same anyway.
  • Rolling session cookies: You could randomly regenerate the session using session_regenerate_id(). This will update the session ID of the client creating the request, and any other client using the same ID will then be logged out because they are sending the old session ID. Actually, you could do this on every request which will ensure that only the current client is using the current session.
SilverlightFox
  • 32,436
  • 11
  • 76
  • 145
  • It sounds really interesting, but also too much work that I cannot do personally, the project I'm working on simply doesn't have enough priority for this. Log in as each other, you mean on the machine itself? Maybe I'm trying to hard for something that's not really important... – Anyone Jan 26 '14 at 16:38
  • I mean if you stopped them sharing the session ID, wouldn't users just share their account details instead? You could prevent the latter by ensuring each user is only logged in once. Anyway, I've updated my answer with a couple more options. – SilverlightFox Jan 26 '14 at 18:27
  • Sadly my "session" cookie is not something that I can regenerate easily. The applications could implement this, but the "master key" needs to be safe or it has no effect... Panopticlick seems good, I'm going to check if I can use that. Thanks! – Anyone Jan 26 '14 at 19:22