6

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

Jason Logsdon
  • 507
  • 5
  • 19
  • 1
    Sometimes it is difficult to do the Security 101 things in Ruby. I stopped trying to use it for programs that had security requirements. TLS configuration was one of the pain points. – jww Mar 11 '18 at 23:41
  • 1
    I would simply put an Nginx in front of the ruby app and let it take care of these requirements instead of focusing too much on code changes – Tarun Lalwani Mar 12 '18 at 07:54
  • Thanks @TarunLalwani. Do you happen to have a link to something describing how to implement that? – Jason Logsdon Mar 12 '18 at 12:23
  • Not that I straightaway know of but I can write an answer if you are open to using Nginx as such – Tarun Lalwani Mar 12 '18 at 12:50
  • I'd prefer the rails option, but if doing it through Nginx ends up being the way to go I'm not adverse to it at all. If there's not a decent option in the next day or so, go ahead and write it up and I'll mark yours as correct. Thanks again! – Jason Logsdon Mar 12 '18 at 14:12
  • 1
    Sorry for a delayed response, got occupied and lost answering this. There was one good library which I found that you could use. Please explore https://github.com/tobmatth/rack-ssl-enforcer – Tarun Lalwani Mar 20 '18 at 10:57

1 Answers1

2

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.

ErvalhouS
  • 4,178
  • 1
  • 22
  • 38