如何安全地获取正在运行的ASP.NET站点的域名

时间:2013-03-22 21:51:56

标签: asp.net security http iis

我在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服务器的请求。

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

目前还不清楚“安全”是什么意思,但主机标题的整个要点是允许浏览器指定它想与之交谈的主机。

RFC 2616Request-URIHost标题有几点要说:

  

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

     

...

     

最常见的Request-URI形式是用来识别a      源服务器或网关上的资源。在这种情况下绝对      必须传输URI的路径(参见第3.2.1节,abs_path)      Request-URI,以及URI(权限)的网络位置      在Host标题字段中传输。

     

...

     
      
  1. 如果Request-URIabsoluteURI,则主持人是其中的一部分    Request-URI。请求中的任何Host头字段值必须是    忽略。
  2.         

    ...

         

    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标题。)