Session security - cookies vs sessionStorage vs ..

Posted by jmls on 08-May-2011 13:47

Being new to this area, and paranoid, I've been reading up a lot on session and session securiry.

Unfortunately, this has led me to be even more paranoid. Let alone more confused

I always read that the best premise was to detect if a SessionID had been set - if not redirect to login page, authenticate and set appropriately. This sessionID is then passed on every request back to webspeed, which then can reload the user session.

It always bugged me, though - if someone were able to get hold of the sessionID, could they simply not "playback" that sessionid and therefore impersonate the original user ?

I then read this page : http://en.wikipedia.org/wiki/Session_fixation

*Shudder*

Long story short - I have come up with a strategy that I think works, but would prefer it some kind and wise owls would cast their eye over it and voice their opinion.

#1 Use SSL

#2 Use Apache 

#3 Remove all server identifiers from responses

#4 Use the SSL_Session_ID (http://httpd.apache.org/docs/2.2/mod/mod_ssl.html) to find a session record in the database. If no record exists, (or session has expired see #7) refer browser to login page.

#5 Use email address for the user id, and a 30s time-based one time password  (I use Google authenticator on iPhone or Android, although you can use hardware tokens as well)

#6 if user id and password match, create a new session record in the database

#7 Set an expiry time on the session record that expires 120s after the last request from that user

With this, there are no cookies , no url parameters , you have encrypted transmissions  and expiring sessions.

Thoughts ?

All Replies

Posted by jmls on 08-May-2011 14:14

Damn, forgot #8

#8 On login, create a CLIENT-PRINCIPAL that can be exported into the session table which can then be imported and set for the duration of the request

Posted by Matt Baker on 08-May-2011 20:57

Your training paranoia is incomplete.

#1 Use SSL. Properly configured.  With proper certificates so that users don't ignore any warning about invalid certificates.  Turn off SSL v2 (and maybe v3 and only allow TLS) as it has known vulnerabilities.

#2. Make sure the webserver is setup properly to be very restrictive with execution and read permissions.  No directory indexes and such, no write permissions anywhere.

#3 Cross-site scripting prevention has to be enforced in the development cycle for every page.  This means that any place where you accept user input that can ever possibly be reflected back into a web page, that input is considered untrusted and is properly purged of anything resembling a script or a link to a URL. Not doing this allows someone to inject their javascript into someone  else's session so they can read their web pages and send back data using  XHR calls to a different web server.  Most browsers ask the user if  they want to allow it.  Pressing yes is really easy if you don't understand the question.  See #8.

#3.5 Webspeed generally isn't vulnerable to SQL injection because the syntax is different, but not because it isn't immune.  If you are using dynamic queries that involve data accepted from a user, then you must protect your queries properly from returning more data than what that user is expected to see.

#4.  Minimum password requirements are in order.  See #8.

#5.  Appropriate monitoring software to detect if someone is attempting bruce force or configuration that can prevent it.

6.  You need to make sure there is a firewall between the messenger running on the webserver, and the actual webspeed broker.  Make sure that firewall is locked down to only allow communication on the required ports between the mesenger, broker, nameserver, and agents.

7.  Want to go further?  Client side certificates.

8.  Human factor.  Most security relies on human factors, not technological factors.  Make sure users of your really sensitive application know not to give out/write down/or share with the IT guy doing maintenance any of their login information.  See #8.

1  is to hide your session ID from the appropriate user.

2. is to prevent someone from bypassing its use

3. Is to prevent one valid login from stealing all the data accessible to other users of the app.

4. Otherwise bruteforce becomes an option.

5. All the SSL in the world won't help if a weak user/password can be guessed.

6.  Every webserver has holes.  Including Apache.  Especially in 5 years from now when you're not managing it.  For fun, run your webserver in a VM, so if you wake up at 2 o'clock in the morning thinking its been hacked you can wipe it with a backup copy that you have carefully been maintaining.

7.  Overrated.  But give a nice sense of security.

8.  See #8.

In your list:

7 is just going to annoy people.  Ever been to a website that kicks you out after two minutes while waiting for you to finish typing a long description?  Two minutes is a short interruption of someone's work by a phone call or writing down a note to oneself.  Try this: set your screensaver on your PC to require a really long password.  At least as long as your user name, and password.  Then change it to start in two minutes .  Then every time your screen saver kicks in, after you log back in, make sure you close whatever program you were working on without saving any data and restart it.  Run that for a few days and see how it works.  That is what your users will experience on your website.  Idle times are good, but make sure it is appropriate to the application.

3 is pointless unless you are not doing the rest.

4.  But what happens if your client says, I like IIS?

4, 5, 6, 8 are all appropriate and recommended.

Dont' try regenerating session cookies (suggested in the wiki article on session fixation) .  Modern apps make liberal use XHR, iframes.  Both run async.  You can end up kicking your user out by accident if two requests run in a slightly different timing.  See comments on 7.

Referer checking is pointless.  Spoofing these is trivial.  There are browser plugins that do it.

IP checking can be valuable but limited if all your users are behind the same firewall.  SSL deals with this.

Fixed typo

Posted by jmls on 09-May-2011 00:50

That has got to rank as one of the more helpful replies of all time! Thanks.

#1 SSL - of course, properly configured. I was going to use certificates from Verisign

#2 Will do

#3 I was thinking that CSRF would be (almost) impossible, as

     a) I am not using any cookie for validation - the session ID comes form the SSL sessionId, which is grabbed from apache

     b) to login, each person must supply a one-time password. Once this password has been used, you cannot use it again, and this password expires after 30s automatically

     c) as it is one-time, the password is invalid in any other session

#3.5 Understood

#4 See #3(b)

#5 We are implementing Snort - is that good enough ? What sort of configuration would prevent a brute-force attack (see #3(b) )

#6 Understood.

#7 We've tried this. A real PITA (oh, how users get confused about installing certificates) And the IT guys don't help (what do you mean that you've got to install something on the pc to access the site?) . It also means that you have to have the certificate installed on every machine that you may want to access the site from

#8 After 20 years, I *still* have users writing their username and password down on yellow sticky pads. To mitigate this, see #3(b)

Timeouts: Will change to 15 minutes (seems to be a banking "standard")

IIS: the plan is to ship a virtual appliance to handle all of the web server stuff, and another to handle the application / db (if required)

Many thanks for the detailed explanation. I really do think that this is one of the areas where Progress could recomend a best practices guide, which explains in detail why you would want to implement such a step.

Posted by Matt Baker on 09-May-2011 11:15

For more information than just wikipedia, it was just pointed out to me a website that deals with these kinds of questions.

https://www.owasp.org/index.php/Main_Page

Lots and lots of practical information for developers and admins.

This thread is closed