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

C# HttpListener:侦听具有显式主机名的端口(无顶级通配符),c#,httplistener,C#,Httplistener,假设我有一台具有IP的机器,例如183.41.22.22。我想侦听所有将发送到本地主机上该IP的端口43的HTTP消息。事实上,我对发送到此端口的所有消息并不感兴趣,只对发送到https://183.41.22.22:443/CustomerData/ 的文档说明我应该添加前缀。他们举了一个例子:http://www.contoso.com:8080/customerData/ 这是否意味着我应该添加前缀https://183.41.22.22:443/CustomerData/?或者我应该使用

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

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

这是否意味着我应该添加前缀
https://183.41.22.22:443/CustomerData/
?或者我应该使用
https://localhost:443/CustomerData/

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

但是,文件警告:

不应使用顶级通配符绑定(http://*:80/和)。顶级通配符绑定会创建应用程序安全漏洞。这适用于强通配符和弱通配符。使用显式主机名或IP地址,而不是通配符

什么是显式主机名?是零件
客户数据

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

什么是显式主机名?是零件客户数据吗

主机名通常被称为“域”。看见此外,警告还包含更多信息(可能为了简洁起见,您省略了这些信息,但其中包含重要信息):

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

RFC部分指的是。这是HTTP/1.1规范的一部分,早在web的早期人们就开始使用它了。一个主机(一个“机器”),用来简单地监听(通常)端口80并为客户端请求的页面提供服务。但当网络开始得到更广泛的应用时,就需要在一台机器上“托管”多个网站。您可以使用DNS将
foo.com
bar.com
指向同一IP,但机器不知道是发送
foo.com
主页还是发送
bar.com
。因此引入了主机头;WebBrowser(更准确地说:http客户端)可以让服务器知道他们感兴趣的主机以及可以提供的正确页面


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

您可以从cmd.exe执行ping以查看本地主机设置为什么>ping localhost“我应该使用”您是否尝试过以及发生了什么?尽管前缀
https://*8080
(和其他端口)起作用,但我无法测试警告的漏洞。所以我不确定使用这个前缀是否安全
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);
    };