我非常关注我构建的网络应用的安全性,因此我一直在使用各种工具来抓取我的每个应用。
虽然在编程方面可以完成的所有工作,以及Active Record等现成课程都没有预见到,但是有一个问题我不断收到警报,我不知道从哪里开始修复它。
我在Unicorn
和Nginx
后面Rails 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.
当然,无论如何......我所理解的这种易受攻击性通常是无害的,但在各种网络应用程序中可能会有害,具体取决于它们的种类。
我该怎么做才能阻止这种攻击?感谢您的任何建议。
答案 0 :(得分:3)
我找到了一种绕过行为并停止获取警报的方法。我不知道这是否是最佳方式,因此接受评论,建议和新答案。
我们走了。
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
答案 1 :(得分:3)
允许可疑请求到达您的代码不是最佳做法;你让自己对所有尚未听说过的攻击持开放态度。主机头欺骗可能会导致非常严重的问题,应该防止这些攻击。话虽这么说,这个答案可能会更好地放在ServerFault中;)。
一个流行且简单的解决方法是通过简单地忽略具有可疑主机头的传入请求来完全避免该问题。在安全性方面,您希望忽略每个具有与您的系统不完全匹配的主机头的请求。在Nginx中,这是通过在端口80上设置默认服务器(如果使用HTTPS则设置端口443)来完成的,除了返回444(非标准Nginx代码大致转换为“COLD SHOULDER”)之外什么都不做:
server {
listen 80 default_server;
listen 443 default_server;
return 444;
}
此问题的一个问题是,某些托管解决方案(如AWS)会在主机标头中提供动态IP地址的自动运行状况/延迟检查。如果您删除这些请求,您的实例将从负载均衡器中删除,并且您无法从Web浏览器访问您的站点。您需要将逻辑放在默认服务器中以传递这些请求并忽略所有其他请求。
答案 2 :(得分: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