This blog is part of our Rails 5 series.
Adding HTTPS support is one of the first steps towards enhancing the security of a web application.
Even when a web app is available over
some users may end up visiting the
http version of the app,
losing the security
It is important to redirect users
https URLs whenever possible.
Forcing HTTPS in Rails
We can force users to use HTTPS
config.force_ssl = true.
If we look at Rails source code,
we can see that
when we set
config.force_ssl = true,
is inserted into our app’s middleware stack :
is responsible for doing three things :
httprequests to their
secureflag on cookies to tell browsers that these cookies must not be sent for
Add HSTS headers to response.
Let us go through each of these.
Redirect all http requests to their https equivalents
In Rails 5, we can configure
the behavior of redirection
In previous versions of Rails,
http request was redirected to
it was done with an HTTP
Browsers cache 301 redirects.
When forcing https redirects,
if at any point
we want to test the
http version of the page,
it would be hard to browse it,
since the browser would redirect to the
Although this is the desired behavior,
this is a pain during testing and deploying.
Rails 5 lets us specify the status code for redirection,
which can be set to
307 for testing,
and later to
301 when we are ready for deployment
We can specify the options for redirection in Rails 5 as follows :
If a redirect status is not specified,
requests are redirected with a
301 status code.
There is an upcoming change
to make the status code used for
redirecting any non-GET, non-HEAD http requests
307 by default.
Other options accepted by
redirect key are
Set secure flags on cookies
By setting the
Secure flag on a cookie,
the application can instruct the browser
not to send the cookie in clear text.
Browsers which support this flag
will send such cookies
Setting secure flag on cookies is important to prevent cookie hijacking by man in the middle attacks.
In case of a “man in the middle” attack,
the attacker places oneself between the user and the server.
By doing this, attacker aims to collect cookies which
are sent from user to server on every request.
However, if we mark the cookies with sensitive information as
those cookies won’t be sent on
This ensures that the browser
never sends cookies to an attacker
who was impersonating the webserver
http end point.
config.force_ssl = true,
ActionDispatch::SSL middleware sets the
Secure flag on all cookies by default.
Set HSTS Headers on Responses
HSTS or “HTTP Strict Transport Security” is a security enhancement by which applications can specify themselves as HTTPS-only to complying browsers.
HSTS capabilities of a browser can be used by sending appropriate response headers from the server.
When a domain is added to the HSTS list of a browser,
the browser redirects to the
https version of the URL without the help of the server.
Chrome maintains an HSTS Preload List with a list of domains which are hardcoded into chrome as HTTPS only. This list is also used by Firefox and Safari.
Rails 5 has a configuration flag
to set the
in the HSTS header and can be used as follows :
We can also specify a
max-age for the HSTS header.
Rails 5 by default sets the
max-age of HSTS header to 180 days,
which is considered as the lower bound by SSL Lab’s SSL Test .
This period is also above the 18 week requirement
max-age mandated for inclusion in browser preload list.
We can specify a custom max-age by :
In Rails 5, if we disable HSTS by setting :
Rails 5 will set the value of expires header to 0, so that browsers immediately stop treating the domain as HTTPS-only.
With custom redirect status and greater control over the HSTS header,
Rails 5 lets us roll out
HTTPS in a controlled manner,
and makes rolling back of these changes easier.