c# - 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);
};
解决方案
什么是显式主机名?它是 CustomerData 的一部分吗?
主机名就是通常所说的“域”。请参阅URL 的组成部分。警告还包含更多信息(您可能为了简洁而遗漏了这些信息,但它包含重要信息):
如果您控制整个父域(而不是易受攻击的),则子域通配符绑定(例如,
*.mysub.com
)不存在这种安全风险。*.com
有关详细信息,请参阅rfc7230 第 5.4 节。
RFC 部分指的是HTTP Host 标头。这是 HTTP/1.1 规范的一部分,当人们在网络早期开始在主机上运行多个网站时引入。主机(“机器”)用于简单地侦听(通常)端口 80 并提供客户端请求的页面。但是当网络开始变得更广泛使用时,需要在一台机器上“托管”多个网站。您可以使用foo.com
和bar.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
.
推荐阅读
- angular - 为什么在 Angular 中删除组件模板中的 DOM 元素是不安全的
- python-3.x - 如何在 32 位操作系统(Windows 10)上下载 python 64 位软件包
- emacs - 如何在 emacs (doom emacs) 中禁用当前行“突出显示”
- python - 检查指定目录中是否存在任何 mp3 文件
- java - 在 KMM 项目中添加对 java 库的依赖
- c# - C# 代码使用 SQL 成功执行,但在数据库中检查时它们仍然显示空值
- c# - 正则表达式查找所有匹配项,除了那些被字符包围的匹配项
- c# - UWP MVVM NavigationView BackButton - 按下时检测
- if-statement - Google App Script IF 函数仅检查一行,并将结果应用于所有行
- maven - Jenkins 构建失败并显示“由于 process.env.CI = true 将警告视为错误”