Skip to content

Instantly share code, notes, and snippets.

@victorlhlam
Last active August 5, 2019 13:44
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save victorlhlam/7019359 to your computer and use it in GitHub Desktop.
Save victorlhlam/7019359 to your computer and use it in GitHub Desktop.
Rails 3.1+ force_ssl & HSTS problem

Rails 3.1 introduced force_ssl. You can add config.force_ssl = true in application.rb.

By enabling force_ssl, Rails send a HSTS (HTTP Strict Transport Security) header which will expired in a year.

So if you enabled force_ssl once, even you change the config value to false later, the browser you used to open you app before will still remember this website (using domain to identify) require to use HTTPS, and redirect you to HTTPS connection automatically. You may use chrome://net-internals/#hsts to check the domain list in Google Chrome.

If you really need to fall back to HTTP connection, you may need to apply the following code. The setup is to force Rails send a new HSTS header which will be expired immediately. When a browser open your Rails application, the browser will expire the HSTS record.

# Add Rack SSL Enforcer in Gemfile
# https://github.com/tobmatth/rack-ssl-enforcer
gem 'rack-ssl-enforcer'
# Change in application.rb
MyApp::Application.configure do
# ...
# repeat this line if you added force_ssl to production.rb or other enviornment configuration files
config.force_ssl = false
# ...
# configure Rack SSL Enforcer
# set the HSTS expires value to 0
# you may add some other options to control the pages you want to apply SSL
config.middleware.use Rack::SslEnforcer, :hsts => { :expires => 0 }
end
# restart your application after finish
@godfat
Copy link

godfat commented Oct 23, 2013

Interesting... Or maybe this without an extra gem?
I didn't test it though.

class ApplicationController < ActionController::Base
  before_filter :expire_hsts
  # or in Rails 4:
  # before_action :before_filter

  private
  def expire_hsts
    response.headers['Strict-Transport-Security'] = 'max-age=0'
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment