force_ssl在Rails中做什么?


84

在上一个问题中,我发现我应该设置nginx ssl终止并且不让Rails处理加密的数据。

那么为什么存在以下内容?

config.force_ssl = true

我在生产配置文件中看到了此注释。但是,如果期望nginx将处理所有ssl内容,以便我的rails应用程序不处理加密数据,那么该怎么config.force_ssl = true办?

如果我知道我将一直使用Nginx,是否应该在生产中将其保留为注释?

Answers:


77

不仅会强制您的浏览器将HTTP重定向到HTTPS。它还将cookie设置为标记为“安全”,并启用HSTS,每一个都是防止SSL剥离的很好的保护措施。

即使HTTPS保护“ https://example.com/yourapp ”上的应用程序免受MITM攻击,但如果有人进入您的客户端和服务器之间,他们也可以轻松地使您访问“ http://example.com/yourapp ” 。没有以上两种保护措施,您的浏览器将很高兴将会话cookie发送给执行MITM的人员。


1
force_ssl的来源包含此选项启用的HSTS的指示
agios

13
@agios这是每个控制器的单独force_ssl属性。该force_ssl配置变量,其安装Rack::SSL中间件,它确实能够在默认情况下HSTS
布伦特皇家-戈登

:@agios你找错了地方github.com/rails/rails/blob/...
jmera

4
听起来config.force_ssl = true应该是默认值,为什么Rails团队将其注释为默认值?
亨利·杨

55

设置config.force_ssl包括ActionDispatch::SSL。该ActionDispatch::SSL文档描述了以下功能(为清楚起见添加了重点):

请参阅包括在这里和ActionDispatch :: SSL的文档在这里

DOCS

该中间件将在时添加到堆栈中config.force_ssl = true,并通过中设置的选项进行传递config.ssl_options。它执行以下三个工作来强制执行安全的HTTP请求:

  1. TLS重定向: 使用相同的URL主机,路径等将http://请求永久重定向到https://。默认情况下启用。设置config.ssl_options 为修改目标URL(例如redirect: { host: "secure.widgets.com", port: 8080 }),或设置 redirect: false为禁用此功能。

  2. 安全cookie:在cookie上设置secure标志,以告知浏览器不要将它们与http://请求一起发送。默认启用。设置 config.ssl_optionssecure_cookies: false禁用此功能。

  3. HTTP严格传输安全性(HSTS):告诉浏览器将该站点记住为仅TLS,并自动重定向非TLS请求。默认启用。配置config.ssl_optionshsts: false对禁用。设置config.ssl_optionshsts: { … }配置HSTS:

    • expires:这些设置将保留多长时间(以秒为单位)。默认为 180.days(推荐)。符合浏览器预载列表的最低要求为18.weeks
    • subdomains:设置为true告诉浏览器将这些设置应用于所有子域。这样可以保护您的Cookie免受子域中易受攻击的站点的拦截。默认为true
    • preload:广告此站点可能已包含在浏览器的预加载HSTS列表中。HSTS会在您初次访问之外的每次访问中保护您的网站,因为它尚未看到您的HSTS标头。为了缩小这一差距,浏览器供应商提供了内置HSTS网站的列表。转到https://hstspreload.appspot.com提交您的网站以供收录。要关闭HSTS,仅删除标题是不够的。浏览器将记住原始的HSTS指令,直到其过期为止。而是使用标头告诉浏览器立即使HSTS过期。设置hsts: false是的快捷方式hsts: { expires: 0 }

请求可以选择退出重定向exclude

config.ssl_options = { redirect: { exclude: -> request { request.path =~ /healthcheck/ } } }

3
“请求可以通过以下方式退出重定向exclude:-警告:此功能仅在Rails 5中最近才添加,因此不适用于我们在Rails 4.2或更低版本上使用的功能
jonleighton

1
我相信exclude全局选项在Rails 5之前已经存在很长时间了,因此语法略有不同:config.ssl_options = { exclude: proc { |env| env['PATH_INFO'].start_with?('/healthcheck/') } }serverfault.com/a/517401
jwadsa​​ck

12

此设置通过将HTTP请求重定向到其HTTPS对等方来强制执行HTTPS。因此,访问的浏览器http://domain.com/path将重定向到https://domain.com/path

将设置保留为注释状态将允许两种协议。

您仍然必须配置Web服务器以处理HTTPS请求。


1
但是,如果您在nginx级别启用HTTPS(通过将所有内容都通过重定向到HTTPS redirect 301 https:...),那么不是所有内容都将通过https进行,因此config.force_ssl = true实际上不会做任何事情(因为什么都不会是http)?还是这里有更深层的安全原因?
崔stan涛

2
@TristanTao是的,这同样适用。但是即使那样,我仍然保持config.force_ssl启用状态,以防万一有人从Web服务器的配置中删除重定向。
Stefan 2014年

2
要注意卫生署,config.force_ssl比控制器force_ssl在这里多对固定会话劫持的cookie方面有所不同:eq8.eu/blogs/...
equivalent8

1
还请注意,同时拥有config.force_ssladd_header Strict-Transport-Security max-age=...;将导致2个Strict-Transport-Security标头
Victor Ivanov '18年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.