Rails: HOST Header Attack漏洞

3
我非常关注我构建的Web应用程序的安全性,因此我一直在使用各种工具来爬取我的每个应用程序。虽然已经完成了所有可以通过编程完成而Active Record等现成类没有预见到的工作,但我仍然收到有一个问题的警报,我不知道从哪里开始解决这个问题。我正在运行Unicorn,它位于NginxRails 4.1之后。我一直收到的警报是:
    An attacker can manipulate the Host header as seen by the 
web application and cause the application to behave in 
unexpected ways. Developers often resort to the exceedingly 
untrustworthy HTTP Host header (_SERVER["HTTP_HOST"] in PHP). 
Even otherwise-secure applications trust this value enough to 
write it to the page without HTML-encoding it with code equivalent to:

<link href="https://_SERVER['HOST']" (Joomla)

...and append secret keys and tokens to links containing it:

(Django, Gallery, others)

....and even directly import scripts from it:

(Various) 

下面是建议内容:
The web application should use the SERVER_NAME instead
of the Host header. It should also create a dummy vhost 
that catches all requests with unrecognized Host headers. 
This can also be done under Nginx by specifying a non-wildcard 
SERVER_NAME, and under Apache by using a non-wildcard serverName 
and turning the UseCanonicalName directive on. Consult references 
for detailed information.

当然,无论什么都可以。我所理解的这种漏洞是普遍无害的,但在不同类型的Web应用程序中可能会造成危害。
您需要做什么来阻止这种攻击呢?感谢任何建议。
3个回答

4

我找到了一种方法来规避此行为并停止接收警报。我不确定这是否是最好的方法,因此评论、建议和新答案均可接受。

下面进入正题。

application_controller.rb

class ApplicationController < ActionController::Base
    before_action :debug_headers

private
    def debug_headers
        if request.env['HTTP_X_FORWARDED_HOST']
            request.env.except!('HTTP_X_FORWARDED_HOST') # just drop the variable
        end
    end # def

end # class

3
允许可疑请求到达您的代码并不是最佳实践;这样做会使您自己面对所有您尚未听说过的攻击。主机头欺骗可能会导致非常严重的问题,应该防止这些攻击。话虽如此,这个答案可能更适合放在ServerFault上;)
一个流行而简单的解决方法是通过简单地忽略具有可疑主机标头的传入请求来完全避免这个问题。在安全术语中,您希望忽略每个传入请求,其中具有与您的系统不完全匹配的主机标头。在Nginx中,这是通过在端口80(以及如果您使用HTTPS,则为端口443)上设置一个默认服务器来完成的,该服务器什么也不做,只返回444(一个非标准的Nginx代码,大致翻译为“冷肩”):
server {
    listen 80 default_server;
    listen 443 default_server;
    return 444;
}

这种方法的一个问题在于,一些主机解决方案(例如AWS)提供了使用动态IP地址作为主机头进行自动健康/延迟检查的功能。如果您放弃这些请求,您的实例将从负载均衡器中删除,您将无法通过Web浏览器访问您的站点。您需要在默认服务器中添加逻辑,以传递这些请求并忽略所有其他请求。


0

这可能更适合作为某种中间件:

# config/environments/production.rb

config.action_controller.default_url_options = { host: "example.com" }

并且:

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  before_action :protect_from_host_header_attack

  def protect_from_host_header_attack
    env['HTTP_HOST'] = default_url_options.fetch(:host, env['HTTP_HOST'])
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接