4

EDIT: I changed the title of this post from "How to manage sessions in webapps?" to "How to secure store sessions values in webapps?" as it might have been misleading

In the recent months I happened to encounter interesting scenarios that made me wonder on how to manager web apps sessions.

Some months ago I read about a SQL-Injection in Joomla 3.4 that would allow an attacker to perform a session hijacking. This is possible because Joomla 3.4 stores in the database the value of each user's session that connects to Joomla. What is interesting is that a couple of weeks ago I performed some on a friend's domain he built a loooot of time ago. His web site is so old that he's still using Joomla 1.1. I could immediately find a SQL-Injection in one of the plugin he installed, so I remembered of the session table and I looked for that. I found it, and I tried to show him the effect of the vulnerability. The thing is that .... I couldn't. The values stored in the database are different from the one the browser receives. I checked the Joomla source code and it turns out that Joomla 1.1 generates a pseudo-random number, performs some md5 operations with that number, and sends to the browser the pseudo-random number and stores in the database the result of the md5 operations. In this way I simply couldn't perform a session hijacking at all.

I also tried to inform the Joomla community about this but they don't seem to care about it. To me it seems quite important, a 10 years old software wouldn't allow an attacker to perform a session hijacking in case a SQL-Injection is found while the new version would.

I started to wonder on what would be the best way for managing sessions values. Why storing them on the database? Why not simply using what the back-end programming language is providing (like session_start in php)?

What do you think about it?

Federico
  • 183
  • 2
  • 9
  • 2
    The Joomla community probably don't care about the Joomla1.x sessions as they are no longer supported, and the code has undergone a huge change since then. – gabe3886 Sep 07 '16 at 13:24
  • That is true, but still why not taking the past into consideration if it's safer? – Federico Sep 07 '16 at 14:43
  • the old stuff is vulnerable, you just don't know how to hack it. The new stuff is probably better in that it takes longer to hack than MD5. if it takes longer than the session duration, it's safe. – dandavis Sep 07 '16 at 20:09
  • 1
    I really don't understand this comment. My point is that a SQL-Injection anywhere in the NEW version of Joomla is good enough to perform a session hijacking since the sessions values are stored in plaintext in the database. Isn't this a problem? If no, why? – Federico Sep 08 '16 at 08:46
  • I like OWASP cheat sheet that lists a number of best practices. – Kirill Sinitski Sep 07 '16 at 13:21
  • I couldn't find there something related to whether or not a session value should be stored in the database and how it should be stored. It only says this "The storage capabilities or repository used by the session management mechanism to temporarily save the session IDs must be secure, protecting the session IDs against local or remote accidental disclosure or unauthorized access." which Joomla! 3.4 is not doing while Joomla! 1.1 was doing. – Federico Sep 07 '16 at 14:47

2 Answers2

5

Yes, it is best practice to hash session tokens within the database. This way sessions cannot be hijacked if the data is exposed. Session tokens themselves should be generated with at least 64-bits of entropy.

Therefore, value provided within cookie = token, value stored in database = token hashed.

As of 2016, SHA-2 is recommended to create the hash. Note that salts are not needed for values generated using sufficient entropy.

A database server is often required for server-side session storage where servers are clustered (although a caching layer can be used instead). Although you can use PHP custom handlers in order to do this, it appears that the Joomla authors decided to roll their own, which is vulnerable to data extraction attacks as you mention.

It is also best practice to restrict access to the storage mechanism. For example, a database account with write access to the table can be used for login and logout and updating the session expiry, and a database account for read access for checking the login session. The rest of the application could use a database account that cannot access the sessions table at all. A secret "pepper"/"system-wide salt" could be used in order to mitigate other attacks where the session table could be written to.

SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
  • Thanks, a complete answer finally. I'll try to contact them again and see if they will consider fixing it. – Federico Sep 08 '16 at 14:04
0

No.

There's a lot of sleight of hand in the code you've shown us, but no real security magic.

Generating ids

If I log into my bank's website and get a session cookie with value 435812, I don't need to be a particularly 733T hacker to think that I might see something interesting if I change this to 435811, 435810, ...

Session IDs need to be unpredictable, but at the same time unique. Using a cryptographic hash is a good way of creating a random and sparse set of values. Coincidentally, most implementations output a value which portable across different representations (think urlencode, htmlentities, mysqli_real_escape_string etc) without additional escaping.

Retrieving the session The whole point of session data is that it is information stored on the server which can be retrieved at a later date. That means subsequent requests from a user must map to the same dataset. From the code you've shown us, Joomla 1.1 appears to do this by maintaining a lookup table mapping the cookie value to the session id. If you can inject SQL, then you can probably inject SQL with a join or a sub query in it.

Threat modelling What's even worse than the lack of protection this provides, is that it makes enumerating the sessions even easier - since a list of the available sessions is accessible in the database.

But the SQL-injecting blackhat is just one threat model. Code injection is also a risk (particularly on unmaintained, off-the-shelf CMS's like Joomla. Putting the session id directly into the session cookie and using a file based handler is just as vulnerable if the attacker can inject PHP code into the system.

Then there's the possibility of attacking the storage directly - either in place or from a backup to discover what data is in the session.

best way for managing sessions values

Storing them in a database is the second lowest common denominator after storing them using the default handler on the filesystem. It does simplify separation of session data between vhosts on a shared hosts (though not much). It's also easy to scale to multiple devices serving up the same site. And if the code does not have the usual select privileges on the underlying table but works through privilege separation (e.g. using stored procedures running as a different DB uid) then they cannot be enumerated.

However this again has limited applicability, and doesn't address the case where the data is compromised.

My solution was to encrypt the session data with an randomly generated key which is not stored on the server at all. Hence the data is protected at rest. There are limits to this approach - it limits capacity and would be a PITA for support. There may be other issues I have not foreseen.

symcbean
  • 18,278
  • 39
  • 73