3

I am wondering if it is smart to hash my session IDs before writing sessions to the session storage, in order to prevent session ID disclosure.

I am writing an application in PHP on top of the Symfony framework. By default PHP stores sessions as files in a directory readable by the PHP process using the session ID as part of the file name. The problem I see is that, if there is a local file inclusion bug or RCE in the application, an attacker can easily list all valid session IDs and hijack sessions.

Alternative session storage for PHP exists, such as Redis or Memcache, but these suffer from the same flaw. You can easily enumerate all keys in Redis or memcache and thus get a list of valid session IDs.

My idea for mitigation is very simple. Instead of storing sessions using the session-ID as the key, use the hash(session-ID) as the key instead. If an attacker then enumerates all existing keys, he still does not have any session IDs. Performacne matters and sessions are relatively short lived (as opposed to e.g. passwords) so I would use a fast hash like SHA-256 or BLAKE instead of e.g. bcrypt for hashing the session IDs.

My question: Does this make any sense? Does this buy me any extra security? Or does a local file inclusion bug or RCE already mean "Game Over" and is this just security theatre?

I can't be the first person to see this possible threat, but I cannot find any mention of this, or of hashing session IDs as a good mitigation or defense-in-depth. Perhaps I just lack the right vocabulary to put into Google?

1
  • I've not completely thought through your setup, but in general terms, storing hashed session IDs is a good idea, for similar reasons that storing hashed passwords is a good idea (same applies to password reset tokens too). It's not a super important control, but given that it's quite easy to implement, I do recommend it in my training course.
    – paj28
    Dec 16, 2019 at 15:49

3 Answers 3

2

LFI on session file is possible, but there are plenty of other options like /proc/self/environ, file descriptors, web server logs, raw database files, SSH/FTP/mail logs, an uploaded file or a temporary uploaded file located in /tmp is also possible, so you gain very little security through obfuscation from doing this. If the attacker can enumerate all session files they can just try all of them until one works. You would be better off spending the would be development time hardening your server or reviewing your code.

2
  • If the attacker can enumerate all session files they can just try all of them until one works but if I use the hash as key instead of the session ID, an attacker cannot try them, right? He has no way of getting the correct session ID for any of the session files. Dec 16, 2019 at 16:55
  • 1
    If the attacker has another bug that lets them enumerate files on the disk they can leak the session filenames, bugs in code bases rarely exists in isolation, there are likely multiple bugs that can be combined. But it hardly matters because session files is only one vector. If you have LFI you cannot rely on session obscurity to keep you safe as any multiform POST request with a file upload to any PHP file will create a temporary file under /tmp so there is always a possibility an attacker can exploit it. If you have LFI and a phpinfo page then this is 100% reliably exploitable
    – wireghoul
    Dec 16, 2019 at 17:03
0

Based on my experience, it is not a common security requirement and not even pen-testers suggest it.

Here a few considerations:

  • The reason may be related to performances vs security: nowadays you should use hash algorithm like bcrypt which are slow on purpose (from ~250 ms up to ~1 s), this is acceptable for one single log-in request but it does not scale well for N requests.

  • Leaking password has a big impact on the final users, instead leaking session IDs can be managed more easily and transparently.

  • Passwords are usually long live objects, session ID short ones.

  • If someone has RCE on your server he/she can already (theoretically) access the final data, he/she could also create/replace an hashed session.

  • With hashed sessions you surely have an advantage if an attacker find a read-only type vulnerabilities or in case of data breaches with some valid session ID.

My final suggestion would be find the best trade-off with your team (e.g. hashing session but using a faster hash or storing the plain session ID only in memory), taking into account the related risk of your data (e.g. bank info or pizza orders info) and prioritizing the hardening tasks to do on your app/server.

PS: OWASP (a good reference point for web security) does not mention it, except in case of session ID exposed in logs

3
  • 1
    Or, use cryptographic cookies stored on the client with no server state at all. Oct 1, 2021 at 22:48
  • @multithr3at3d, if you mean something like JWT cookies, I guess it could work but with these approach many things can be done wrong with huge impact (weak keys, alg none allowed, etc..) and an attacker with a full RCE could theoretically still get the sign key (or encryption key) from the server. Oct 4, 2021 at 10:52
  • yes, JWT is one possible method. Any decent library plus proper key choice will mitigate those issues. If your threat model goes as far as accessing the key, almost nothing will be good enough for you. Oct 4, 2021 at 11:51
0

If an attacker can read files directly outside of your web directory, then session IDs are the least of your worries. If they can write to files, then it is time to nuke it from orbit.

Because of that, mangling the session IDs when storing them doesn't buy you any extra security. It simply gives you some obscurity.

However, it's still useful to take steps to keep session IDs secure. The most useful tool for this purpose is session ID regeneration. The PHP manual recommends regenerating the session ID every 15 minutes in security-sensitive applications. OWASP has suggested regenerating the session ID with every request, though I don't know what their current guidance is.

Regardless of how often the session ID is regenerated, it must always be regenerated when a user logs in, to prevent session fixation attacks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.