This is a blog post version of the Rails Security talk that I gave at Rubyfuza 2017 in Cape Town earlier this year.
I'll also be giving this talk (or an updated version of it) for Ruby Dev Summit, a free online conference, in October this year.
If you don't know who I am, I'm a (primarily Ruby) developer at Kisko Labs.
Kisko is a small software consultancy based in Helsinki, Finland. We're heavily invested in Rails as it's our primary development tool so Rails is near and dear to our hearts.
You can find me in all the usual places:
- Twitter: @matiaskorhonen.fi
- GitHub: matiaskorhonen
- Email: [email protected]
- Web: matiaskorhonen.fi
- Blog: right here…
First some things you should know about me…
I tend to start too many side projects (and sometimes I even finish some of them)
To help with my brewing hobby, I build an iOS app for browsing BJCP Style Guidelines.
I've also made Piranhas, a book price comparison app. It lets ou search for books on different stores and it calculates the shipping costs and currency conversions for you.
I'm also working on a product called TLS.care. It monitors your sites and alerts you if your SSL certificate is about to expire or if it has been revoked.
Most of this is advice that will apply to any web app, regardless of what framework you're using. However, there are some Rails specific implementation suggestions as that's our primary tool at Kisko.
In fact it's likely that there won't be a person targeting you but rather it'll be a bot or script executing attacks against as many targets as possible.
Automation gives attackers all the same advantages that it does elsewhere:
- Mass exposure
- Reduced overhead
- Tools for everyone regardless of skill
- Dramatically increased odds of success
This is a sentiment that is almost universally wrong. All legitimate sites have at least once thing of value to malicious actors: reputation.
Your site's good reputation can be used to facilite malware installs, dodgy ads, or the attacker may simply choose to hold your site hostage.
At Kisko we love Rails, it increases out productivity and let's us achieve great things for our clients in a shorter time than we could otherwise.
How does it fare security-wise?
It comes with support for securely stored sessions and passwords and encourages you to adopt good development practices.
In fact, you get all of this for “free” when you use Rails.
If you work with Rails, you should read the Ruby on Rails Security Guide.
Assuming that you've chosen Rails and are using all the security features that it supplies out of the box, what more can you do?
I think we are well past the point where it's acceptable not to use HTTPS for production apps.
Our clients or users might not know to require it, but as experts we know better.
Even if you believe that your site “has nothing valuable”, do you trust every actor that might attempt to inject content onto your page?
This is happening, and it's being perpetrated by major ISPs in major countries. This is not some theoretical threat…
Studies suggest that ad injection affects as many as 5% of browsers.
Both Chrome and Firefox now mark login pages as “Not Secure”.
This will soon be the case for all pages with forms on them!
And the plan is to gradually extend this to all pages served over plain HTTP.
And if that isn't enough, there are also technical reasons to use HTTPS. For example HTTP 2.0 is effectively HTTPS only and some advanced browser features require HTTPS.
What's more, if some shady wifi hotspot injects ads or malware onto your site your users are going to blame you, not the network.
Anyone can get a free certificate from Let's Encrypt. If you use AWS, Amazon will issue your a free certificate for use on their services.
If you use Heroku, it already has support for automated certs from Let's Encrypt.
Let's Encrypt are also working on adding support for wildcard certs by January 2018
This redirects visitors to the HTTPS version of your site, enables Strict Transport Security (HSTS), and marks cookies as secure.
HSTS means that repeat visitors will automatically use HTTPS after the first visit.
Secure cookies are only sent over HTTPS, never plain HTTP.
Luckily for us there's a really handy tool we can use: the SSL Labs server test
It's free and it does a great job of telling you were you might have gone wrong.
If you click “learn more” get to read interesting things about logjam and FREAK attacks, DHE_EXPORT ciphers, Elliptic-Curve Diffie-Hellman Key Exchange and prime numbers.
Luckily for us there's a shortcut.
People far smarter than me have created the Mozilla SSL configuration generator.
If your site meets the technical requirements, you can submit it for inclusion in the HSTS preload list. This list is used by Chrome, Firefox, Opera, Safari, IE 11 and Edge.
This is how MDN explains what a CSP is, personally I found that nigh incomprehensible.
My version is that it's a header which tells the browser where assets (scripts, stylesheets, fonts, and so on) can be loaded from.
A CSP header can be used to reduce the potential attack surface of your site.
Even with the fairly relaxed CSP that I'm forced to use on Piranhas, it's blocked some weird requests.
I'm still not sure what or why some thing was trying to load this on my site, but I do know that I want no part of it.
There's a large variety of directive available for allowing/blocking scripts, images, fonts, and more.
Report URI is a handy free service for collecting the violation reports.
Adding a CSP header to a long standing site can be tricky because you have to figure where you're loading everything from. It's much easier if you're starting a new project
You might not even be aware of everything that's being loaded (Facebook buttons, YouTube embeds, analytics, and so forth).
… I recommend the SecureHeaders gem from Twitter.
It provides support for CSP headers (and a lot more) and it also provides support for overriding the policy on a controller or action level.
The defaults are mostly the same as the Rails defaults, with a couple of extras.
The CSP header, X-Download-Options
(which mitigates some IE vulnerabilities), and X-Permitted-Cross-Domain-Policies
which restricts Adobe Flash player’s access to data.
As the name suggests, like the normal header except that violations are not enforced, only reported. You can see the violations in console or via the report-uri
.
This is also great if you're making changes to an existing policy.
My feeling is that it's not worth the pain, I'm not the only one.
For a more detailed look at the issues with HPKP, see this blog post by Scott Helme (the creator of Report URI): I'm giving up on HPKP
How ever if you're slightly crazy or work at an organization with the resources and discipline to handle it, here's a couple of tips.
In short: be very, very careful. Make backups keys and store them offline. You may also need to anticipate switching to a different key algorithm in the future.
- Twitter: @matiaskorhonen.fi
- GitHub: matiaskorhonen
- Email: [email protected]
- Web: matiaskorhonen.fi
- Blog: right here…