Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
38 lines (28 sloc) 3.19 KB
layout: post
title: HSTS in Rails
date: 2015-01-12 11:00:00
updated: 2015-01-12 11:00:00
coordinates: 50.725696 4.576064
proofread: no
<div class="narrow-col">
<blockquote cite="">
<abbr title="HyperText Transfer Protocol">HTTP</abbr> Strict Transport Security (<abbr title="HTTP Strict Transport Security">HSTS</abbr>) is a recent specification aimed at stopping a certain type of man-in-the-middle attack known as <abbr title="Secure Socket Layer">SSL</abbr> Stripping. By default, when a user types &ldquo;<code></code>&rdquo; into their browser, the browser prefixes that with &ldquo;<code>http://</code>&rdquo;. A man-in-the-middle attack can hijack the connection before the server redirect to <abbr title="HyperText Transport Protocol over SSL">HTTPS</abbr> gets back to the browser, spoofing the site and potentially luring the user into providing sensitive data to the attacker.
<p>Rails has a simple configuration setting to enable <abbr title="HyperText Transfer Protocol">HSTS</abbr> when your application already supports <abbr title="Secure Socket Layer">SSL</abbr>. You can activate it by uncommenting the <code>config.force_ssl</code> setting in your `production.rb` environment file. Once deployed this will add the Strict-Transport-Security headers to each request telling the browser all future requests should go over <abbr title="HyperText Transport Protocol over SSL">HTTPS</abbr>. Rails adds an expiry date 1 year in the future and does not add the <code>includeSubDomains</code> part as it doesn't know if all subdomains are served over <abbr title="Secure Socket Layer">SSL</abbr>.</p>
<h2>Adding our own header</h2>
<p>A year is a bit long for the project I am working on. At the worst, some visitors would have problems accessing our site up to one year when we decide to stop serving over <abbr title="Secure Socket Layer">SSL</abbr>. We could add a <code>max-age=0</code> for a while and hope most earlier visitors visit the site again which would remove the <abbr title="HyperText Transfer Protocol">HSTS</abbr> cache or every visitor could manually empty their cache but this will cause a lot of work for our helpdesk. Rails also doesn't add <abbr title="HyperText Transfer Protocol">HSTS</abbr> to subdomains out-of-the-box so we rolled our own.</p>
<p>Add the following to your ApplicationController:</p>
{% highlight ruby %}
before_action :force_ssl, if: -> { Rails.env.production? }
def force_ssl
response.headers['Strict-Transport-Security'] = 'max-age=2678400; includeSubDomains' # 31 days
{% endhighlight %}
<li class="vcard">Great <a title="HSTS on Rails" href="" class="url"><abbr title="HyperText Transfer Protocol">HSTS</abbr> on Rails</a> article by <span class="fn n"><span class="given-name">Scott</span> <span class="additional-name">W.</span> <span class="family-name">Bradley</span></span>.</li>
<li>The <a title="Session Hijacking @ RailsGuides" href="">Session Hijacking</a> chapter in the RailsGuides.</li>
You can’t perform that action at this time.