When you can’t use cookies
So, I’ve looked at the utility and security of cookies and I’ve at looked the utility and security of sessions. It you’ve been following along, then you know that sessions are great, they provide a secure way to verify who you are talking to.
Sessions are great. Great that is — until you can’t use them.
Sessions depend on cookies, and you can’t always use cookies. When can’t you use cookies? Safari in an iframe for one. I do a lot of integration work, add ons for various platforms, and typically you add on is embedded via iframes.
Let’s recap the advantages of Rails sessions:
- They encrypt the data the store, making it tamper proof.
- They the values are effectively random, making it virtually impossible to guess someone else valid session.
- They are not unavailable to JavaScript, protecting them from cross site scripting attacks.
This is awesome. And you should use sessions if you can. In fact, repeat after me:
I will always use cookie based sessions, unless I really, really, can’t.
The main security concern out of the box for Rails specifically is that session cookies are sent in the clear over HTTP, making them vulnerable to sniffing and in turn session hijacking. This is fixed by having your app always use HTTPS and by setting the secure flag on the session cookies, telling the browser to never send the cookie over HTTPS.
If you do something other than use cookies, the above is the bar you have to hit in terms of security, and doing so ranges from the easy to the impossible.
Easy
Easy is using HTTPS security. Cookies are set with all requests,
secure or otherwise, which is why the secure flag is
necessary. Whatever you do, you control the URLs you are talking to
and can insure they all use HTTPS. However, it would be wise to take
out some insurance and configure your app to only use HTTPS by setting
config.force_ssl = true
in config/environments/production.rb.
Medium
Medium is making your data opaque, and you may not care. Generally, it’s considered good practice not to expose database IDs. It’s low risk, however, because database IDs are usually sequential, they can give away information like how many users you have, the relative age of accounts, and so on. It’s a judgment call, but if it matters to you app or business model, you’ll need to do it.
This is be solved by encrypting IDs you want to protect.
Impossible
Impossible is emulating the HttpOnly
flag. That functionality, is
deeply baked (see what I did there?) into the browser. You simply
can’t do anything like it. Your data will be on the page and if it’s
on the page, it’s vulnerable to Javascript attacks.
The good news is you’re in control of your page, if you follow best practices (beyond the scope of this post, but well documented) and, especially if you don’t have to display any user generated content, you should be able to lock it down.
Know that we know how to attack the security challenge, the key is to securely authenticate something that replaces the session cookie. In the final post of this series, I’ll do just that with a JSON Web Token (JWT).
Comments