HttpListener:使用显式主机名(没有顶级通配符)监听端口

4
假设我有一台机器,IP地址是183.41.22.22。我想监听所有发送到该IP地址的本地主机端口43的HTTP消息。实际上,我并不真正关心发送到此端口的所有消息,只关心发送到https://183.41.22.22:443/CustomerData/的消息。 class 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);
    };

你可以在cmd.exe中执行ping命令来查看localhost的设置 > Ping localhost - jdweng
1
虽然前缀 https://*8080(以及其他端口)可以工作,但我无法测试所警告的漏洞。因此,我不确定使用此前缀是否安全。 - Harald Coppoolse
1个回答

5
“显式主机名”是什么?它是CustomerData这一部分吗?
主机名通常被称为“域名”。请参见URL的组成部分。此外,警告还包含更多信息(您可能因简洁而省略了它,但它包含重要信息):
子域通配符绑定(例如*.mysub.com)如果您控制整个父域,则不会存在此安全风险(而不是容易受攻击的*.com)。有关更多信息,请参见rfc7230 section-5.4
RFC部分是指HTTP Host header。这是HTTP / 1.1规范的一部分,当人们在Web早期开始在主机上运行多个网站时引入了它。主机(“机器”)过去只需在(通常为)端口80处侦听并提供客户端请求的页面。但是,随着Web的广泛使用,需要在单台计算机上“托管”多个网站。您可以使用DNS使foo.combar.com都指向相同的IP,但是那么计算机将不知道是发送foo.com主页还是bar.com的主页。因此,引入了Host标头;网络浏览器(更正确地说:http客户端)然后可以让服务器知道他们感兴趣的主机,并且可以提供正确的页面。
请注意,域名的每个部分(例如sub.domain.foo.co.uk潜在地指向不同的主机(但它们也可能全部指向同一个主机)。使用顶级域名通配符(例如*.com,甚至更糟糕:*)是潜在的风险,因为任何人都可以获得一个.com域名(myevildomain.com),并将其指向您的服务器。如果您使用*.company.com,则除了company.com之外,没有人能够控制子域。为什么这是一种安全风险是另一个故事,但要点是,使用通配符*.com会使您的应用程序响应任何以.com结尾的host头,而*.company.com将防止您的应用程序响应(可能被欺骗的)客户端请求myevildomain.com

在查看了RFC之后,看起来所有的*问题都与可能将流量转发到意外的内部目标或更糟糕的是缓存数据x域有关(因此它们可以被多个虚假域请求淹没)。至少这是我从中得出的唯一结论。你知道其他的风险吗?(直觉告诉我应该有,考虑到微软文档的措辞,但在RFC中似乎没有明确列出) - eglasius
只是想补充一下,一个令人烦恼的问题就是在这里描述的问题 https://dev59.com/o6nka4cB1Zd3GeqPTsdq#50342157。事实上,这就是我最终阅读这个答案的原因。考虑到链接中的内容,在某些情况下(多个网络接口),我们几乎没有选择,只能允许通配符,并在处理请求时可能首先检查域名。 - eglasius
微软提到的安全问题似乎被称为DNS重绑定攻击:https://en.wikipedia.org/wiki/DNS_rebinding。“该攻击可通过使受害者的Web浏览器访问私有IP地址上的计算机并将结果返回给攻击者来用于突破私有网络。”攻击者首先将恶意DNS指向其外部服务器,并让用户加载带有恶意脚本的页面,然后立即更改DNS以指向私有IP,因此在同一恶意域中已加载的脚本现在可以向私有IP发送请求。 - eglasius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接