HttpListener:侦听具有显式主机名的端口(无顶级通配符)

Har*_*lse 4 c# httplistener

例如,假设我有一台有 IP 的机器183.41.22.22。我想侦听将发送到本地主机上该 IP 的端口 43 的所有 HTTP 消息。事实上,我对发送到该端口的所有消息并不真正感兴趣,只对发送到的消息感兴趣https://183.41.22.22:443/CustomerData/

HttpListener 类的文档说我应该添加一个前缀。他们举了一个例子:http://www.contoso.com:8080/customerData/

这是否意味着在我的情况下我应该添加 prefix https://183.41.22.22:443/CustomerData/?或者我应该使用https://localhost:443/CustomerData/

或者,由于我的计算机专用于此任务,我确信我的计算机上的任何其他人都不应收到发送到端口 443 的任何消息。因此,根据相同的文档,我还可以使用通配符:http://*:443

然而,文档警告:

不应使用顶级通配符绑定(http://*:80/ 和http://+:80 )。顶级通配符绑定会造成应用程序安全漏洞。这适用于强通配符和弱通配符。使用明确的主机名或 IP 地址而不是通配符。

什么是显式主机名?是那个部分吗CustomerData

对于那些感兴趣的人,代码的简化部分(没有适当的可能性结束程序)

using (var httpListener = new HttpListener())
{
    httpListener.Prefixes.Add("https://*:443/");
    httpListener.Start();

    while (true)
    {
        var context = httpListener.GetContext();
        var httpRequest = context.Request();

        // fill the response
        string responseText = this.CreateResponseText(httpRequest);
        byte[] buf = Encoding.UTF8.GetBytes(responseText);
        context.Response.ContentLength64 = buf.Length;
        context.Response.OutputStream.Write(buf, 0, buf.Length);
    };
Run Code Online (Sandbox Code Playgroud)

Rob*_*III 5

什么是显式主机名?是 CustomerData 部分吗?

主机名就是通常所说的“域”。请参阅URL 的组成部分。此外,警告还包含更多信息(您可能为了简洁而省略了这些信息,但它包含重要信息):

如果您控制整个父域(而不是容易受到攻击的 ),则子域通配符绑定(例如*.mysub.com)不会存在此安全风险。有关详细信息,*.com请参阅rfc7230 第 5.4 节。

RFC 部分指的是HTTP 主机标头。这是 HTTP/1.1 规范的一部分,是在网络早期人们开始在一台主机上运行多个网站时引入的。主机(“机器”)用于简单地侦听(通常)端口 80 并为客户端请求的页面提供服务。但是,当网络开始得到更广泛的使用时,就出现了在一台计算机上“托管”多个网站的需求。您可以使用 DNS 使foo.combar.com都指向相同的 IP,但机器将不知道是否发送foo.com主页或 的bar.com主页。所以引入了Host头;然后,网络浏览器(更准确地说:http 客户端)可以让服务器知道他们对哪个主机感兴趣,并且可以提供正确的页面。

请注意,域的每个部分(例如sub.domain.foo.co.uk都可能引用不同的主机(但它们也可能全部指向同一主机)。使用顶级域通配符(例如*.com,甚至更糟:)*是一个潜在的风险,因为任何人都可以获取.com域(myevildomain.com)并将其指向您的服务器。如果你使用*.company.comnobody但company.com可以控制子域。为什么这是一个安全风险是一个完全不同的故事,但其要点是使用通配符*.com将使您的应用程序响应任何以hostwhile 结尾的标头,.com并将*.company.com阻止您的应用程序响应(可能被欺骗的)客户端请求myevildomain.com