【发布时间】:2018-09-02 15:48:39
【问题描述】:
在这种情况下,防火墙的存在是有原因的:阻止外部请求访问内部资源。
假设我有两台 HTTP 服务器在运行:一台在 8080 端口,另一台在 8081 端口。
8080 端口上的服务器是一个可公开访问的基于 Node 的网站(在此示例中由 express 提供支持),并在每个请求上运行以下代码,这基本上是一种向用户请求数据的简单 CDN - 定义的 URL(在 X-Cool-URL 标头中)并将该请求的正文返回给我网站域下的用户。 request 是 request 模块,req 是 express 请求对象,res 是 express 响应对象。 (很明显,这个特定的代码既不实用也不防错,但它是一个不错的例子。)
const url = req.get("X-Cool-URL"); // some example user input value
request(url, (error, response, body) => { // request said arbitrary resource
res.send(body); // send response back to user
});
8081端口上的服务器是一个HTTP服务器,通过内部请求做事;通过端口 8081 的外部网络被防火墙阻止,这是有充分理由的。绝不应向其发送任意用户定义的数据。假设我不是这个 Web 服务器的程序员,并且无法控制或访问它的代码。该服务器对任何给定的请求输入究竟做什么是无关紧要的。重要的是,允许向其发送任意数据会带来安全风险。
...但我可以从任何外部命令行运行此命令。
curl -H "X-Cool-URL: http://localhost:8081/something/malicious" http://example.com:8080
这就带来了一个问题:用户只能使用我的公共网络服务器通过localhost:8081在内部网络下请求私有网络服务器。我仍然希望人们能够通过我的网络服务器在端口 8080 上请求其他公共域,我仍然希望能够作为开发人员在内部请求 8081,但我不希望其他人能够利用我的服务器任意访问8081,不受防火墙限制。我怎样才能让用户无法使用我的公共网络服务器来请求任何内部资源?
我想要保护的端口可能并不总是明确和已知的,因此简单地通过我的 Web 服务器阻止 8081 是不切实际的。仅阻止对localhost 的所有请求也是不切实际的,因为还有其他方法可以请求内部资源(例如使用127.0.0.1)。甚至可以设置指向本地资源的 DNS 记录,因此仅将一组 URL 列入黑名单也行不通。白名单也不是一种选择,因为它会破坏 CDN 的要点,让客户端能够请求任何外部资源。我对一种在每种情况下都能检测 URL 是否为内部 URL 的方法感兴趣。
【问题讨论】:
-
你控制哪台服务器?服务于端口 8080 的代理还是服务于端口 8081 的代理?
-
假设我只控制8080上的那个。
标签: node.js security networking request localhost