首页 > 解决方案 > HttpListener:监听具有显式主机名的端口(无顶级通配符)

问题描述

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

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

这是否意味着在我的情况下我应该添加前缀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);
    };

标签: c#httplistener

解决方案


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

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

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

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

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


推荐阅读