I feel that I have a responsibility to be as verbose and clear as possible on matters that concern security. tl;dr: Rivered now has HTTPS and requires it. This was proactive, not reactive; nothing bad has happened.
A discussion in IRC prompted me to get SSL sorted on Rivered, and from now on HTTPS is not only available, it is required. Cookies are also now marked as secure which means if you initially access Rivered over HTTP you are not vulnerable to session hijacking. I changed Rails’ secret token which will have the effect of expiring any existing cookies to make sure people swap to secure ones (it looks like this doesn’t happen by default and existing users would still have insecure cookies).
In detail, here are the steps I took to achieve this:
- I purchased an SSL certificate from RapidSSL for $49. I don’t know if this is standard practice, but when you get a certificate for a ‘www.’ subdomain the certificate is also valid for the root domain. This is very handy otherwise visitors manually typing the address without ‘www.’ would get an invalid certificate warning.
- I added the certificate to Heroku. This is a painless process and increases the cost of hosting Rivered from $9/month to $29/month which means I am now making a loss on the product (Rivered currently has 9 monthly paying users at $2/month each and a handful of yearly-paying users), but obviously it’s pretty negligible either way at this stage.
- I updated the CNAME record for www.rivered.io to point to the new Heroku endpoint. Heroku use a completely separate set of hostnames for SSL-enabled sites.
- I was previously using an Amazon S3 bucket to redirect from http://rivered.io to http://www.rivered.io. But Amazon don’t let you (easily) use HTTPS with S3 buckets so I had to revert to an older method; using my server & nginx to perform the redirect. More and more I wish I was using DNSimple who provide a sensible ALIAS service and even cheaper SSL certificates.
- As of version 3.1 Ruby on Rails provides a one-line configuration change to force SSL and switch to using secure cookies. I noticed that my existing cookie was not marked as secure by this (I could be wrong…but that was my first impression) so I took the additional measure of changing the secret token for the app which has the side effect of invalidating all existing cookies forcing them to be recreated hopefully with the secure flag set. Existing users will have to log in again; a small price to pay to avoid session hijacking.
Not having SSL for so long was inexcusable. This was a mistake and laziness on my part and I should’ve sorted it sooner. However:
- Although Rivered was not SSL, the payment gateway was.
- The amount of private information Rivered stores is as little as possible; unless you consider the RSS feeds you choose to subscribe to private.
- The main vector of attack the lack of SSL enables is sniffing user’s traffic. Rivered was vulnerable to both session hijacking (through cookie sniffing) and your password being sent in the clear when you first log in. Both are important issues, but are also issues only really present when you are on an insecure network (and for the latter, someone not already logged in), at which point it would be wise to take precautions anyway as many services do not use encryption all the time. I also assumed that of all the services a user might use Rivered is not exactly that important.
- A lack of SSL changes nothing about how the security of the application codebase itself. Rivered uses Devise which uses bcrypt with the standard level of password-hashing cost. This is vastly superior to many websites you probably use every day, despite not being anything special.
Any feedback or thoughts about anything I may have missed is very much appreciated.