When you can’t use cookies

2 minute read

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