简体   繁体   English

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

[英]How do I securely get the domain name of the running ASP.NET site

I've encountered some issues with spoofing of the Host value in HTTP transactions. 我在HTTP事务中遇到了欺骗Host值的一些问题。 In order to close security holes related to these types of attacks, I need to securely detect what the domain of the running ASP.NET site. 为了关闭与这些类型的攻击相关的安全漏洞,我需要安全地检测正在运行的ASP.NET站点的域。 Unfortunately, all of the references I find suggest you use Request.ServerVariables["HTTP_HOST"] or Request.Url.Host . 不幸的是, 我发现的所有引用都建议您使用Request.ServerVariables["HTTP_HOST"]Request.Url.Host By submitting invalid HTTP packets, I have been able to set invalid host values and observer the behavior they're causing with both function calls. 通过提交无效的HTTP数据包,我能够设置无效的主机值,并观察它们在两个函数调用中引起的行为。 The behavior I'm seeing is different depending on the type of .NET environment I use. 我看到的行为是不同的取决于我使用的.NET环境的类型。

In IIS 6, the injected value always shows up, no matter if I access the request directly in an MVC Controller action, or in a location that requires me to access the values through HttpContext.Current.Request . 在IIS 6中,无论我是直接在MVC Controller操作中访问请求,还是在需要我通过HttpContext.Current.Request访问值的位置,注入的值总是显示出来。

In the Visual Studio 2012 ASP.Net Development Server, I only see the injected values in library code we deployed to the project through a NuGet package. 在Visual Studio 2012 ASP.Net开发服务器中,我只看到我们通过NuGet包部署到项目的库代码中的注入值。 In the NuGet package I have to use the HttpContext.Current since the code runs outside of the scope of the web application. 在NuGet包中,我必须使用HttpContext.Current因为代码在Web应用程序范围之外运行。 When I stay within the scope of the web application's namespace, even if I have to call the HttpContext.Current , it will provide the correct unspoofed value. 当我保持在Web应用程序命名空间的范围内时,即使我必须调用HttpContext.Current ,它也会提供正确的非默认值。

For all of this testing, I have been using ASP.NET 4.0. 对于所有这些测试,我一直在使用ASP.NET 4.0。 Has this behavior changed in ASP.NET 4.5 and IIS 8? ASP.NET 4.5和IIS 8中是否更改了此行为? Is there a way to securely get the domain name? 有没有办法安全地获取域名? It is also possible to do the same attack against PHP , but Apache has a way that can prevent these types of attacks . 也可以对PHP进行相同的攻击 ,但Apache有一种方法可以防止这些类型的攻击 Does IIS? IIS?

Example of the code I've been having problems with: 我遇到问题的代码示例:

string siteName1 = HttpContext.Current.Request.ServerVariables["HTTP_HOST"];
string siteName2 = HttpContext.Current.Request.Url.Host;

Example of an invalid HTTP Packet: 无效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

I've done my testing with the Firefox extension Live HTTP headers which has allowed me to quickly record and replay my requests to the web server. 我已经使用Firefox扩展Live HTTP标头进行了测试,这使我能够快速记录并重放我对Web服务器的请求。

In IIS you could setup the site's bindings so that it only gets requests matching particular host header value(s). 在IIS中,您可以设置站点的绑定,以便它只获取与特定主机头值匹配的请求。

That way if someone tries to spoof the host header value, your website won't even see the request. 这样,如果有人试图欺骗主机标头值,您的网站甚至不会看到请求。

Not exactly an answer to your question, but possibly an solution to your problem. 不完全是您的问题的答案,但可能是您的问题的解决方案。

It's unclear what you mean by "securely", but the entire point of the Host header is to allow the browser to specify the host it intended to talk to. 目前还不清楚“安全”是什么意思,但主机标题的整个要点是允许浏览器指定它打算与之交谈的主机。

RFC 2616 has a few things to say about the Request-URI and Host header: RFC 2616Request-URIHost头有几点要说:

To allow for transition to absoluteURI s in all requests in future versions of HTTP, all HTTP/1.1 servers MUST accept the absoluteURI form in requests, even though HTTP/1.1 clients will only generate them in requests to proxies. 为了允许在将来的HTTP版本中的所有请求中转换为absoluteURI ,所有HTTP / 1.1服务器必须接受请求中的absoluteURI表单,即使HTTP / 1.1客户端只会在对代理的请求中生成它们。

... ...

The most common form of Request-URI is that used to identify a resource on an origin server or gateway. Request-URI的最常见形式是用于标识源服务器或网关上的资源。 In this case the absolute path of the URI MUST be transmitted (see section 3.2.1, abs_path ) as the Request-URI , and the network location of the URI (authority) MUST be transmitted in a Host header field. 在这种情况下,URI的绝对路径必须作为Request-URI传输(参见第3.2.1节, abs_path ),并且URI(权限)的网络位置必须在Host头字段中传输。

... ...

  1. If Request-URI is an absoluteURI , the host is part of the Request-URI . 如果Request-URIabsoluteURI ,则主机是Request-URI Any Host header field value in the request MUST be ignored. 必须忽略请求中的任何Host头字段值。

... ...

The Host field value MUST represent the naming authority of the origin server or gateway given by the original URL. Host字段值必须表示原始URL给出的源服务器或网关的命名权限。 This allows the origin server or gateway to differentiate between internally-ambiguous URLs, such as the root "/" URL of a server for multiple host names on a single IP address. 这允许源服务器或网关区分内部不明确的URL,例如单个IP地址上的多个主机名的服务器的根“/”URL。

... ...

A client MUST include a Host header field in all HTTP/1.1 request messages. 客户端必须在所有HTTP / 1.1请求消息中包含Host头字段。 If the requested URI does not include an Internet host name for the service being requested, then the Host header field MUST be given with an empty value. 如果请求的URI不包含所请求服务的Internet主机名,则必须为Host头字段指定一个空值。

... ...

The requirements that clients and servers support the Host request- header, report an error if the Host request-header (section 14.23) is missing from an HTTP/1.1 request, and accept absolute URIs (section 5.1.2) are among the most important changes defined by this specification. 客户端和服务器支持Host请求标头的要求,如果HTTP / 1.1请求中缺少Host请求标头(第14.23节),并且接受绝对URI(第5.1.2节),则报告错误是最重要的本规范定义的更改。

... ...

  • Both clients and servers MUST support the Host request-header. 客户端和服务器都必须支持Host请求标头。
  • A client that sends an HTTP/1.1 request MUST send a Host header. 发送HTTP / 1.1请求的客户端必须发送Host头。
  • Servers MUST report a 400 (Bad Request) error if an HTTP/1.1 request does not include a Host request-header. 如果HTTP / 1.1请求不包含Host请求标头,服务器必须报告400(错误请求)错误。
  • Servers MUST accept absolute URIs. 服务器必须接受绝对URI。

In summary, while a conforming HTTP client cannot send the request 总之,符合HTTP的客户端无法发送请求

GET https://example.com/ HTTP/1.1
Host: fakedomain.invalid

to an origin server, an HTTP/1.1 server is required to accept it, use example.com as the host, and "ignore" the Host header. 到原始服务器,一个HTTP / 1.1服务器被要求接受它,使用example.com作为主机,和“忽略”的Host首部。 Request.Url.Host should definitely be example.com ; Request.Url.Host绝对应该是example.com ; if not it's a bug in IIS. 如果不是,它是IIS中的一个错误。 I'm less certain about Request.ServerVariables["HTTP_HOST"] , but a reasonable interpretation of "ignoring" the host header would be to rewrite it to say example.com . 我不太确定Request.ServerVariables["HTTP_HOST"] ,但是对“忽略”主机头的合理解释是将其重写为example.com

(Incidentally, the two other servers I've just tested don't follow the spec either: Apache 2.4.3 assumes that a request to an absoluteURI must be one to a proxy and denies it on that basis, while lighttpd 1.4.28 allows GET http://example.com/ HTTP/1.1 without a Host header.) (顺便提一下,我刚刚测试过的另外两个服务器也没有遵循规范:Apache 2.4.3假设对absoluteURI的请求必须是一个代理并且在此基础上拒绝它,而lighttpd 1.4.28允许GET http://example.com/ HTTP/1.1没有Host标头的情况下GET http://example.com/ HTTP/1.1 。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM