我在HTTP事务中遇到了欺骗Host值的一些问题。为了关闭与这些类型的攻击相关的安全漏洞,我需要安全地检测正在运行的ASP.NET站点的域。很遗憾,all of the references I find建议您使用Request.ServerVariables["HTTP_HOST"]
或Request.Url.Host
。通过提交无效的HTTP数据包,我能够设置无效的主机值,并观察它们在两个函数调用中引起的行为。根据我使用的.NET环境的类型,我看到的行为会有所不同。
在IIS 6中,无论我是直接在MVC Controller操作中访问请求,还是在要求我通过HttpContext.Current.Request
访问值的位置,注入的值始终显示。
在Visual Studio 2012 ASP.Net开发服务器中,我只看到我们通过NuGet包部署到项目的库代码中的注入值。在NuGet包中,我必须使用HttpContext.Current
,因为代码在Web应用程序范围之外运行。当我保持在Web应用程序命名空间的范围内时,即使我必须调用HttpContext.Current
,它也会提供正确的未默认值。
对于所有这些测试,我一直在使用ASP.NET 4.0。 ASP.NET 4.5和IIS 8中是否更改了此行为?有没有办法安全地获取域名?也可以执行same attack against PHP,但Apache has a way that can prevent these types of attacks。 IIS?
我遇到问题的代码示例:
string siteName1 = HttpContext.Current.Request.ServerVariables["HTTP_HOST"];
string siteName2 = HttpContext.Current.Request.Url.Host;
无效HTTP数据包示例:
GET: https://sampledomain.com/Items/Index
Host: fakedomain
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cache-Control: max-age=0
我已经使用Firefox扩展程序Live HTTP headers完成了测试,这使我可以快速记录并重播我对Web服务器的请求。
答案 0 :(得分:1)
在IIS中,您可以设置站点的绑定,以便它只获取与特定主机头值匹配的请求。
这样,如果有人试图欺骗主机标头值,您的网站甚至都不会看到请求。
不完全是您问题的答案,但可能是您问题的解决方案。
答案 1 :(得分:0)
目前还不清楚“安全”是什么意思,但主机标题的整个要点是允许浏览器指定它想与之交谈的主机。
RFC 2616对Request-URI
和Host
标题有几点要说:
允许将来在所有请求中转换为
absoluteURI
HTTP版本,所有HTTP / 1.1服务器必须接受absoluteURI
请求中的表单,即使HTTP / 1.1客户端只会生成 他们在代理请求中。...
最常见的
Request-URI
形式是用来识别a 源服务器或网关上的资源。在这种情况下绝对 必须传输URI的路径(参见第3.2.1节,abs_path
)Request-URI
,以及URI(权限)的网络位置 在Host
标题字段中传输。...
- 如果
醇>Request-URI
是absoluteURI
,则主持人是其中的一部分Request-URI
。请求中的任何Host
头字段值必须是 忽略。...
Host
字段值必须表示 由...给出的源服务器或网关的命名权限 原始网址。这允许源服务器或网关 区分内部不明确的URL,例如根“/” 单个IP地址上多个主机名的服务器的URL。...
客户端必须在所有HTTP / 1.1请求中包含
Host
头字段 消息。如果请求的URI不包含所请求服务的Internet主机名,则必须Host
标头字段 给出一个空值。...
客户端和服务器支持
Host
请求的要求 - 标头,如果Host
请求标头(第14.23节)是,则报告错误 从HTTP / 1.1请求中丢失,并接受绝对URI(部分 5.1.2)是由此定义的最重要的变化之一 说明书...
- 客户端和服务器必须支持
Host
请求标头。- 发送HTTP / 1.1请求的客户端必须发送
Host
标头。- 如果是HTTP / 1.1,服务器必须报告400(错误请求)错误 请求不包含
Host
请求标头。- 服务器必须接受绝对URI。
总之,符合要求的HTTP客户端无法发送请求
GET https://example.com/ HTTP/1.1
Host: fakedomain.invalid
到源服务器,HTTP / 1.1服务器必需接受它,使用example.com
作为主机,并“忽略”Host
标头。 Request.Url.Host
绝对应该是example.com
;如果不是,它是IIS中的一个错误。我对Request.ServerVariables["HTTP_HOST"]
不太确定,但对“忽略”主机标题的合理解释是将其重写为example.com
。
(顺便提一下,我刚刚测试的其他两个服务器也没有遵循规范:Apache 2.4.3假设对absoluteURI
的请求必须是代理的一个,并在此基础上拒绝它,而lighttpd 1.4.28允许GET http://example.com/ HTTP/1.1
没有Host
标题。)