Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally Implementing HSTS, SSL, and Secure Cookies in Rails Based on Domain

I run an application that hosts websites from multiple domains from a single application and server. I am moving some of those domains to SSL, but others are staying at http. I'm running Rails 4.x. I believe I CAN'T just use the

config.force_ssl = true

because that would implement it for all domains, which I don't want.

I know in the ApplicationController I can do something like

force_ssl if: :ssl_required?

def ssl_required?
  return [secure_domain1, domain2, domain3].include? request.domain
end

But as I understand it, that doesn't implement HSTS or secure cookies. My two questions are:

  1. Is there a better way to implement it than what I have above?
  2. If I do go the above route, is there a way to conditionally send secure cooking and implement HSTS for only those domains?

If there is no easy way to enable HSTS or secure cookies, and having those is worth the hassle, I can always split my app and host it on two different servers, with one instance containing all https domains and the other containing only http domains.

Thanks for your thoughts

like image 478
Jason Logsdon Avatar asked Mar 09 '18 17:03

Jason Logsdon


Video Answer


1 Answers

Using Rails to do that is actually not a bad idea, but using NGINX for that would be even better as comments have pointed out. If you really want to pursuit the Rails solution you could do something like that in the very same def:

force_ssl if: :ssl_required?

def ssl_required?
  if [secure_domain1, domain2, domain3].include? request.domain

    #HSTS for Rails <=4
    response.headers['Strict-Transport-Security'] = 'max-age=315360000; includeSubdomains; preload'
    #HSTS for Rails >=5
    response.set_header('Strict-Transport-Security', 'max-age=315360000; includeSubdomains; preload')

    cookies[:secure] = true
    true
  else
    false
  end
end

You could always tune your HSTS header to the desired max-age or use a more idiomatic approach putting #{365.days.to_i} instead of the simple string header.

like image 127
ErvalhouS Avatar answered Oct 29 '22 01:10

ErvalhouS