4

我遇到了一些在 HTTP 事务中欺骗 Host 值的问题。为了关闭与这些类型的攻击相关的安全漏洞,我需要安全地检测正在运行的 ASP.NET 站点的域。不幸的是,我找到的所有参考资料都建议您使用Request.ServerVariables["HTTP_HOST"]or Request.Url.Host。通过提交无效的 HTTP 数据包,我能够设置无效的主机值并观察它们在两个函数调用中导致的行为。我看到的行为因我使用的 .NET 环境类型而异。

在 IIS 6 中,无论我是直接在 MVC 控制器操作中访问请求,还是在需要我通过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 中是否发生了变化?有没有办法安全地获取域名?也可以对 PHP 进行相同的攻击,但是Apache 有一种方法可以防止这些类型的攻击。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 标头完成了我的测试,这使我能够快速记录和重播我对 Web 服务器的请求。

4

2 回答 2

1

在 IIS 中,您可以设置站点的绑定,以便它只获取与特定主机标头值匹配的请求。

这样,如果有人试图欺骗主机标头值,您的网站甚至不会看到该请求。

不完全是您问题的答案,但可能是您问题的解决方案。

于 2013-03-22T22:46:14.040 回答
0

不清楚您所说的“安全”是什么意思,但 Host 标头的全部意义在于允许浏览器指定它打算与之交谈的主机。

RFC 2616Request-URI对and标头有一些话要说Host

为了允许absoluteURI在 HTTP 的未来版本中的所有请求中转换为 s,所有 HTTP/1.1 服务器必须接受absoluteURI 请求中的表单,即使 HTTP/1.1 客户端只会在对代理的请求中生成它们。

...

最常见的形式Request-URI是用于标识源服务器或网关上的资源。在这种情况下,URI 的绝对路径必须作为 传输(参见第 3.2.1 节abs_pathRequest-URI,并且 URI(授权)的网络位置必须在Host标头字段中传输。

...

  1. 如果Request-URIabsoluteURI,则主机是 的一部分 Request-URI。请求中的任何Host头域值都必须被忽略。

...

Host字段值必须代表原始 URL 给出的源服务器或网关的命名权限。这允许源服务器或网关区分内部不明确的 URL,例如单个 IP 地址上的多个主机名的服务器的根“/” URL。

...

客户端必须Host在所有 HTTP/1.1 请求消息中包含一个标头字段。如果请求的 URI 不包括被请求服务的 Internet 主机名,则Host头字段必须为空值。

...

客户端和服务器支持请求标头、如果HTTP/1.1 请求中缺少请求标头(第 14.23 节)Host报告错误以及接受绝对 URI(第 5.1.2 节)是定义的最重要更改之一Host 通过本规范。

...

  • 客户端和服务器都必须支持Host请求头。
  • 发送 HTTP/1.1 请求的客户端必须发送Host标头。
  • 如果 HTTP/1.1 请求不包含Host请求标头,服务器必须报告 400(错误请求)错误。
  • 服务器必须接受绝对 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 假定对 an 的请求absoluteURI必须是对代理的请求,并在此基础上拒绝它,而 lighttpd 1.4.28 允许GET http://example.com/ HTTP/1.1没有一个Host标题。)

于 2013-03-28T03:27:55.790 回答