0

I've been doing a lot of research regarding sesion hijacking and I'm concerned at the number of codebases which seem to have poor implementations of defence against this. I feel I have a good understanding now at how to prevent this, such as:

  1. Always use TLS
  2. Set cookies over TLS, HTTP only and SameSite=Strict
  3. Change the session name from the default (in my case I'm also going to dynamically rotar it every so often with salt)
  4. Regenerate the session ID when a user authenticates / escalates privilege level, logs out etc
  5. Use PHP's strict mode for sessions along with switching off session IDs in URLs, only allowing cookie sessions & increasing the length/bits of the session ID
  6. Validate the IP address of the session
  7. Check the client user agent / browser / device etc
  8. Check the session running time to ensure it hasn't expired (I'm using a custom session handler and storing via the database)
  9. Add a seperate cookie with some other kind of login key / session key / device key hash etc which is used in conjunction with the session ID to verify the session is legitimate
  10. Properly dispose of the old session on logout and when regenerating the session ID

My question here really comes with using the additional cookie to verify the session. When using PHP sessions these automatically close when you exit the browser, so if a user checks "remember me" then I'd need an additional cookie anyway to verify the remember me details. So in this case I'd have: (1) the php session cookie (with the ID), (2) the cookie login key consisting of the device key or IP or some other hash used to verify the session cookie ID within the DB, and (3) the cookie with the remember me hash that automatically instantiates the session when the user visits the site again after closing the browser.

My issue is that I don't like this idea of instantiating a session via a single cookie because it feels very vulnerable... which is exactly why I've gone to such lengths to avoid a single session cookie ID. But if an attacker managed to get the php session cookie, they'd also manage to get the other cookie I set as well, making it pretty pointless. So how exactly can I set this securely or do something so that an attacker could never get all parts to instantiate a valid session? Particularly while using remember me.

The second part of my question is in relation to LAN networks.... let's say that we're in an office building with shared offices, and the network there doesn't use an internal TLS certificate meaning anyone can hijack sessions internally within that network (i.e. Wireshark). This is based on a very real use case as my old work has exactly this setup still in place. In this scenario, how can I tell that the session has come from a different machine? This could be a Coffee shop, McDonalds or any other public wi-fi service too. The only way I can think of is to check with the user agent / device, but again if the hacker (albeit internal) had access to the session cookie, they'd also have access to spoof the user agent etc as well because they'd know what user agent the other user was using.

Chris98
  • 567
  • 1
  • 4
  • 16
  • 2
    It really mostly comes down to using TLS. When you have that, *theoretically*, any cookie can only be hijacked if the attacker has actual access to the user's machine, in which case it's game over anyway. TLS gets you there 99.99999+% of the way, all the other stuff is just the remaining 0.000001% of security an attacker may have to content with if they managed to bypass TLS somehow. IP restrictions can be useful in a non-TLS scenario… but in that case an attacker would probably be directly intercepting the username and password anyway and not need to hijack any cookies. – deceze Dec 23 '21 at 13:19
  • 1
    There is also a problem where the LAN is proxying all HTTPS connections, terminating TLS connections locally, inspecting raw HTTP, and then reconnecting to the origin over an encrypted channel. Sounds edge-case, but this is to a certain degree how Cloudflare works, and they even have an option to connect to the origin without encryption. – Chris Haas Dec 23 '21 at 14:52
  • You're absolutely right I hadn't even considered this possibility or thought about CloudFlare. I guess in this case there's not really a lot that I can do, other than the steps I mentioned above. Maybe I'm just trying to control things that will never be in my control. The only other thing I can think of is using a nonce, but that just seems messy and unnecessary. Plus I'm not sure how much additional protection it would really give anyway that the other things wouldn't... – Chris98 Dec 24 '21 at 16:12
  • I suppose if someone hacks into this over LAN and hijacks the session from there, it's not really my responsibility because that would be an issue within their own network internally. All I can reasonably do is try to put in place as many preventions as possible to try and stop this. – Chris98 Dec 24 '21 at 16:15

0 Answers0