34

Please read this THOUROUGHLY before voting...

So I have seen a lot of session management classes that create a fingerprint via concatenation of user agent and a couple of ip blocks or whatever. They seem to also add a salt and then hash this fingerprint before storing it in a session variable.

This fingerprint generation typically happens every request in order to verify that the current user of the session is in deed the original session user. This is why I am wondering, is the salt and hash really necessary on something like this?

If a hacker can get onto your filesystem to see your session file contents, aren't you already hosed at that point?

Any info greatly appreciated.

dqhendricks
  • 19,030
  • 11
  • 50
  • 83
  • You want to make sure i can not predictably recreate your session key (thus the private salt). If i can, then i dont need access to your server, i can just brute force my way into your system by randomly generating a key until i get in. – Geoffrey Wagner Jun 24 '11 at 15:58
  • 1
    @Geoffrey Wagner first, why would the salt on the server side matter for a brute force attack..? I would be using the same salt server side for anyone trying to impersonate that user to gain access to their session right? for brute force, they still only have to guess the client header inputs in this scenario for an attack because the server does the hashing for them. – dqhendricks Jun 24 '11 at 16:11
  • i retract my statement, i totally wasn't in a server frame of mind, whoops – Geoffrey Wagner Jun 24 '11 at 16:14

8 Answers8

11

Most of it makes sense, but the hashing and salting makes no sense.

If you tie the session to an IP address, then it becomes a lot harder to hijack into a session. This is something I recommend doing, but you don't need to be utterly strict about it. You can just tie to the first three parts of the IPv4 or so. The choice is yours. The more strict IP check the more secure it is, but the less convenient it is for users.

And as for tying the session based on the user agent, that may also help. It must be realized that if you work on an unencrypted channel (HTTP for example), then the user agent check is less useful as it can be reproduced by the intruder as well.

When it comes to salting and hashing, that is useless. They add no strength to your identity checks. The only thing they do is complicate your design. For this matter, I believe they lower your level of security.

As always, a few rules to keep in mind:

  • Use strong session identifiers. This means use good random sources and make sure there are enough bits.
  • Tie the session to an IP, at least to some extent.
  • Tie the session to a user agent, if possible.
  • Use SSL/TLS. Without it, theoretically all session systems are insecure.
  • Secure your session storage. Whether it's filesystem based or database based.
Tower
  • 98,741
  • 129
  • 357
  • 507
  • Any other access from the same user will use the same U-A, so if the user does *any* browsing over HTTP then the attacker can sniff the U-A. – tc. Jul 01 '11 at 23:53
  • @tc that's right. So checking for UA seems a bit more like an extra _thin_ layer of security. – Tower Jul 02 '11 at 12:47
  • You say that the salt + hashing are useless, but at the same time you say you should secure your session storage. It seems to me that using those two things would help in hiding that information so if a hacker gains access to the database but not the exact code to generate those entries, he still cannot know what these are (assuming you do not also save that information in clear somewhere else on the same computer, obviously... like your logs.) – Alexis Wilke Oct 15 '13 at 01:06
4

I can think of two cases where it would be useful:

  1. When the session data is stored client-side. (Like in a cookie.) So, I'd be prevented from taking my cookie to another computer, and I'd be prevented from making up my own cookie contents. (Ok, so this is not a very likely scenario...)
  2. When the session data is stored in some shared server-side resource (i.e., /tmp) and is vulnerable to snooping. In this case, if the snooper is able to see the contents of the session, they'll still be unable to fake a connection to that session because they don't know what data went into the fingerprint.
Alex Howansky
  • 50,515
  • 8
  • 78
  • 98
  • 1. store session data in a cookie? sounds weird, if you are storing it in a session why would also store it in a cookie? 2. this is true, but if your shared server is allowing other account holders to open your tmp files, you have serious security problems anyways... every shared server I have ever been on does not allow you to access other's tmp files. this is a very good point none-the-less however. – dqhendricks Jun 24 '11 at 21:59
  • 1. The cookie *is* the session. Doesn't require any server-side storage. I.e., instead of the cookie holding a pointer to a server-side resource with the data, the data is actually in the cookie. 2. I didn't mean a "(shared server)-side" resource I meant a "shared (server-side)" resource -- i.e., even a private server has a shared /tmp filesystem. And it's not just files. Could be a database table or a memcache cluster. I'm not saying that hashing the fingerprint adds a ton of security, but it's not a horrible idea. At the very least, it gives you a shorter string to store and compare. :) – Alex Howansky Jun 24 '11 at 22:09
  • 1. isn't session data stored 100% inside a cookie just called a cookie haha? 2. are you implying that the session file, which is typically stored in the tmp folder, can be accessed by outsiders? are files stored in tmp easier to gain access to than other parts of the file system because it is a shared resource on the server? any info on this would be great. – dqhendricks Jun 24 '11 at 22:19
  • 1. You say tomato... :) 2. It's possible, certainly. Could be a misconfiguration, or just a lazy sysadmin. But in general, /tmp is not considered to be a good place for session data for exactly this reason -- the session files should be in a subdir owned explicitly by the web server user, and not world-readable. Even if files in /tmp are readable only by the web server user, I can probably see their file names, and then write a 3-line PHP script on my site which can display the contents of anybody else's session file. (Since the script would be run by the web server user...) – Alex Howansky Jun 24 '11 at 22:30
  • I can think of a much better way to fix 2: In the database, store the session data under h(session_id). This means a database dump will not disclose session IDs provided your session IDs have sufficient entropy and your hash is preimage-resistant (both of which are not difficult to achieve). Also, running all scripts as the webserver user is a security hole in the first place... – tc. Jul 01 '11 at 23:57
3

In complement to the response of @Kai Sellgren (+1) which contains some good hints on how to secure your session storage I would add some ideas than can explain the hash & salt on some specific applications.

I'm not talking of application that are using the cookie as a session storage, we still see this for example on Prestashop eCommerce solution, with encryption of the cookie content (why the hell did they decide to store the session on the cookie?). I understand we talk about server side session storage.

The key point is layered Security and in-depth defense:

Compromissions are never boolean things, your are not 'completly compromised' or 'completly secure'. One of the the real history I like about that is the mySpace worm explanation, it shows a real attack and how defensive steps must be break. There's always a new wall. Just one example, I share the same IP as my boss when i'm in the office, and maybe the same browser, this could break a security based only on IP+user-agent.

So in the hash & salt of session stamping we are clearly acting after a few walls have fallen. And kai shows us some of these walls. When he talks about securing the session storage I would add 2 things:

  • it's a really good idea to alter the session.save_path and the open_basedir of each PHP application (and get a separate Virtualhost for each). Rarely done.
  • if your application is installed on a path (like /myapp), add a prefix_path on the session cookie (and fix it for any other app on the same server)

Now Let's imagine a realistic compromission. You've several ways to compromise the session on the server side:

  • The application is running on a website with some other applications running in other paths (or in other domains in the same server). And at least on of theses applications is quite unsecure. At worst server side code could be injected in this app, but some of the security walls (like open_basedir or other chrooting techniques) may prevent this injected code from affecting your separate application (or data).
  • Some of the javascript libraries comes with some test subdirectories containing highly insecure scripts, with not only nice session disclosure but maybe some session fixation or prediction available.
  • The application is shared, and talking about wordpress-like softs you can imagine some platforms sharing a lot of different installations, with different modules and maybe some custom code. On such platforms you'll find settings to allow altering the salt for each consumer, there's a reason for that. One of the website could impact the security of others and clean separation can be harder to do if the applications wants to manage the websites all-in-one.

Your targeted application may get hit by the environment, if the session storage can be shared with some scripts from other application, or from a script in your own application that you did'nt even notice (like these f*** examples in javascript libs, why didn't you suspend php execution on static file directories!)

From this first step of compromission the attacker could potentialy (and in severity increasing):

  • read the session stamps and maybe find which information he should fake to get the same stamp
  • build a new session containing a session stamp valid for his configuration, and then use this new session identifier on your application. Your application will find the session file, and accept him.
  • alter one of your valid session to modify the stamp in the same way

A simple hash of the stamp would make his life harder, but it would just be a wall to break, the salt make this wall really harder to break.

One important point is, from your question, if a guy can alter something in the session storage am I already in a bad mood?. Well, maybe not completly. If it is the only thing the chroot/separation/securization of applications allows him to do this salt will be a nightmare for him.

And the second important point is: should I do this level of in-depth security on every web application?. Answer is no. Overengineering is a bad thing and can reduce the security of your application by the simple fact it became harder to understand and maitin. You do not need to complexify your application if:

  • you've got a pretty good level of session storage separation
  • you're alone on your server, only one application, and not any sort of multisite handling
  • your application security level is so weak that a simple code injection is available on the application, so a session fixation is not needed for an attacker :-)
regilero
  • 29,806
  • 6
  • 60
  • 99
1

I can imagine that the point of hashing that fingerprint information is storage space as the resulting hash has a fixed length.

But to also use a salt doesn’t make much sense to me. Because, as you’ve already said, since that data is stored in the session data storage location, you would already have a bigger problem than session fixation/hijacking if someone would be able to obtain that data.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
1

You can find a plausible solution here: http://shiflett.org/articles/the-truth-about-sessions

Fingerprinting combats session hijacking. The attacker not only needs your session_id, he also needs any sensitive HTTP headers. It adds another barrier for the attacker, albeit one that can be easily overcome.

The hash is there to make the data uniform. The salt is there to obscure the hashing process - so an attacker can not generate a valid fingerprint for his own combination of HTTP headers.

If a hacker is in your filesystem you have bigger problems :D

Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • If the session ID is not securely generated in the first place, you've already lost. The post you linked to gives the example of `12345` and calls it "security thorough obscurity". Guess what? Guessing the User-Agent is even easier than guessing a 5-digit number! – tc. Jun 29 '11 at 23:15
  • "The hash is there to make the data uniform. The salt is there to obscure the hashing process - so an attacker can not generate a valid fingerprint for his own combination of HTTP headers." - Why would hashing server side prevent the attacker from guessing header info? If they are trying to impersonate someones session, the server will hash his guessed headers the same exact way as the stored info before trying to match it. – dqhendricks Jun 30 '11 at 00:27
  • love this article, and all of the comments. – dqhendricks Jun 30 '11 at 01:26
  • @tc the `session_id` is stored in the $COOKIE, the finger print is stored in the session (so on the server) – Halcyon Jun 30 '11 at 07:54
  • @dqhendricks If you read down the comments you'll find a comment Chris "and there's no reason to use md5() or salting at all. This technique, which is valid but a little outdated, is to create a fingerprint that is stored on both the client and the server." – Halcyon Jun 30 '11 at 07:59
  • It doesn't matter where the "fingerprint" is stored, since all the attacker has to do is sniff the correct U-A and IP, which is trivial if you've already sniffed the cookie. – tc. Jul 01 '11 at 02:45
1

A lot of people who don't understand very much about security combine bits of advice floating around the internet in the hope that what they end up with will be "good enough". Tying the session ID to the U-A breaks browser upgrades (which Chrome does fairly often) and tying to the IP address breaks mobility (anyone with a laptop that uses Wi-Fi), and many ISPs don't have contiguous allocations. Anyone who can sniff cookies can also sniff the U-A, and will probably have access to the same IP address because they got the cookie off insecure Wi-Fi behind a NAT.

What you probably do want to do is change the session ID on a login attempt, which is a reliable way to prevent "session fixation" attacks (where the attacker makes the victim load http://example.com/?SESSIONID=foo e.g. through an <img>, waits for you to log in, and now knows the victim's session ID). There is little reason to preserve a session across a login, and you can copy the few things that need to be preserved (e.g. a shopping cart) across.

tc.
  • 33,468
  • 5
  • 78
  • 96
  • Maby I misunderstood you, but browser upgrade/IP change is usually good enough reason to reset session (if you don't make "remeber me" feature, witch is bad on it's own). – XzKto Jun 30 '11 at 07:05
  • IP change is a *terrible* reason to reset the session. It happens all the time on IPv6, or when you move your laptop from work to home, or when your DSL modem reconnects, or... – tc. Jul 01 '11 at 02:46
  • It seems that this really depends on country. On the site I am developing we did a little research and there are less then 1% of users that have more then the last octet changed in their IP more then once a week (of cource we have only about 2k uniques/day so this is not very good statistics). Making them relogin each time doesn't seem to bother them (they have similar activity statistics as others). Do you have some numbers to confirm your post? I am really interested in this. – XzKto Jul 01 '11 at 08:46
  • I said IP change, not moving to a different /24. You also mention "last octet", so presumably you haven't enabled IPv6. I also stand by my claim that anyone who can sniff the session cookie can also sniff the U-A and probably also can use the same IP easily enough, so the "fingerprinting" is of limited use. – tc. Jul 01 '11 at 23:52
  • No, we don't have IPv6 enabled, but author said "couple of ip blocks", so most likely he wasn't using it too. About "anyone who can sniff the session cookie ... can use the same IP": Not really, there are lot's of cookie-specific vulnerabilities: http://en.wikipedia.org/wiki/HTTP_cookie#Cookie_theft_and_session_hijacking and more, IP stealing/faking is much harder and in most cases can be detected. TLDR: you most likely can fake IP only by "hacking" user's computer/network, but there are lot's of ways to steal cookies without it. – XzKto Jul 04 '11 at 06:41
  • @XzKto, pretty much all of the listed ways of "session hijacking" can also be used to steal the user's password without much more effort. ARP spoofing is really not that much more difficult than eavesdropping. – tc. Jul 24 '11 at 21:20
  • as far as I understand the most popular method to steal cookies is XSS attack - you can steal only session this way, no access to password, some bugs in browsers also allow only to steal sessions etc., and I am not sure, but I think that ARP sppofing is close to impossible in modern networks as they now build defences against it straight in hardware (http://en.wikipedia.org/wiki/ARP_spoofing#Defenses). Anyway, even if that is not true stealing IP should be difficult as most of the defences I saw rely on IP filtering. I agree, this is not 100% defence, but one more step for good security. – XzKto Jul 25 '11 at 07:55
  • @XzKtoo, Some "modern" (expensive) networks, sure — those switches will usually also block DHCP and route advertisements except from/to the "legitimate" server. They're also expensive, and doing so comes with a management overhead (you have to configure MAC addresses somewhere), and it's all a moot point with the proliferation of semi-public wireless networks since "stealing" an IP becomes dead easy. It's dead easy even among security professionals (see airpwn). Just use HTTPS. – tc. Sep 09 '11 at 17:59
1

If a hacker can get onto you filesystem to see your session file contents, aren't you already hosed at that point?

If you are using PHP as CGI (like in the case with nginx), then I think no. If you set permissions right then your session files must have read/write permission for PHP user while your PHP files should have only read permissions. So, if you pass the salt from the web server to PHP, then PHP user can't get access to it (he can't create any new/change existing PHP files that can be run by your web server and he can't access web server as it is run on another user), so he can't really hack(change) cookies (only delete them) because he can't get salt. Of course you will have to pass database settings from web server as well.

I never really tried it, so please correct me if I am wrong.

XzKto
  • 2,472
  • 18
  • 18
0

is the salt and hash really necessary on something like this [http client fingerprint]?

The hash might be useful to reduce the number of bytes consumed by the fingerprint inside the session data. So as long as the hashed fingerprint is of a smaller size than the fingerprint itself this can make sense in terms of space reduction. Price is the consumption of system resources to generate the hash.

Does it really make sense? You would need to benchmark this to say so.

How can a salt be helpful then? I must admit, I see no reason for a salt. It would only make sense to make it harder to guess the fingerprint from a hash. But as I do not see any security benefit in hashing the fingerprint (it's kept on the server-side only and is already considerably secure), salting is not adding anything.

In case the session store itself is not considered secure (if that's for the argument), the whole session should be encrypted, not only the fingerprint.

So particularly for the fingerprint, I do not see much use in hashing and salting it.

hakre
  • 193,403
  • 52
  • 435
  • 836