Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 阻止对CDN上的内部资源的请求_Node.js_Security_Networking_Request_Localhost - Fatal编程技术网

Node.js 阻止对CDN上的内部资源的请求

Node.js 阻止对CDN上的内部资源的请求,node.js,security,networking,request,localhost,Node.js,Security,Networking,Request,Localhost,在这种情况下,防火墙的存在有一个原因:阻止外部请求访问内部资源 假设我有两个HTTP服务器在运行:一个在端口8080上,另一个在端口8081上 端口8080上的服务器是一个可公开访问的基于节点的网站(本例中由express提供支持),并在每个请求上运行以下代码,这基本上是一种简单的CDN,从用户定义的URL(在X-Cool-URL标题中)请求数据并将该请求的正文返回给我网站域下的用户request是request模块,req是express请求对象,res是express响应对象。(显然,这段代

在这种情况下,防火墙的存在有一个原因:阻止外部请求访问内部资源

假设我有两个HTTP服务器在运行:一个在端口8080上,另一个在端口8081上

端口8080上的服务器是一个可公开访问的基于节点的网站(本例中由
express
提供支持),并在每个请求上运行以下代码,这基本上是一种简单的CDN,从用户定义的URL(在
X-Cool-URL
标题中)请求数据并将该请求的正文返回给我网站域下的用户
request
request
模块,
req
express
请求对象,
res
express
响应对象。(显然,这段代码既不实用也不防错误,但它是一个不错的例子。)

端口8081上的服务器是通过内部请求执行操作的HTTP服务器;通过端口8081的外部网络被防火墙封锁,这是有充分理由的。不应向其发送任意用户定义的数据。假设我不是这个web服务器的程序员,并且不能控制或访问它的代码。这个服务器对任何给定的请求输入的具体操作是无关的。重要的是,允许向其发送任意数据会带来安全风险

…但我可以从任何外部命令行运行此命令

curl -H "X-Cool-URL: http://localhost:8081/something/malicious" http://example.com:8080
这带来了一个问题:用户只需使用我的公共web服务器通过内部网络下的
localhost:8081
请求私有web服务器即可。我仍然希望人们能够通过端口8080上的web服务器请求其他公共域,我仍然希望能够作为开发人员在内部请求8081,但我不希望其他任何人能够利用我的服务器任意访问8081,而不受防火墙的限制。我如何才能让用户不可能使用我的公共web服务器来请求任何内部资源

我想要保护的端口可能并不总是确定的和已知的,因此通过我的web服务器简单地阻止8081是不实际的。仅阻止对
localhost
的所有请求也不切实际,因为还有其他方法可以请求内部资源(例如使用
127.0.0.1
)。甚至可以设置指向本地资源的DNS记录,因此将一组URL列入黑名单也不起作用。白名单也不是一个选项,因为它会破坏CDN的功能,使客户机能够请求任何外部资源。我对一种在任何情况下都能检测URL是否为内部URL的方法感兴趣。

案例1:您控制端口8080上的代理服务器 因此,如果您控制代理服务器,而不是其背后的web服务器,那么实际上很容易防止类似的事情:您只需要从请求中过滤某些HTTP头,而不是处理这些请求

最安全的方法是使用允许在
X-Cool-URL
标题中使用的主机名白名单。然后只需检查URL是否与白名单匹配。另外,您可以使用黑名单过滤,但这有点麻烦,因为您不仅要考虑<代码>本地主机< /COD>,而且还要考虑各种IP范围。您不希望
X-Cool-URL
指向127.0.0.1、192.168.X.X等任何东西

案例2:您控制端口8081上的后端服务器 如果您无法控制代理服务器过滤哪些请求以及它转发给您的HTTP请求,则必须检查请求的来源。您可以使用以下代码获取原始请求者的详细信息:

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
如果
ip
地址不在允许的范围内,请不要回答请求。通过这种方式,您可以从防火墙后面运行的其他服务器授予访问权限,同时阻止来自代理的访问

开发者访问 一旦实现了这两种机制中的任何一种,您仍然希望允许对后端进行开发访问。最简单的方法是使用一个只有您知道且不容易猜到的密钥。然后将此密钥作为附加HTTP请求头(
X-Cool-secret
)或作为
X-Cool-URL
本身的一部分作为查询参数提供

附加思考 这样的场景本质上是不安全的。一旦您通过公共互联网提供对后端的访问,您就需要为攻击做好准备。即使你的代理可以过滤很多东西,仍然有可能有人找到一条通过它的途径。在同一台物理机器(或VM)上同时运行代理和后端会增加额外的安全风险。一般经验法则:不要这样做

允许从开发机器访问也是有风险的。密钥可能泄露,密码可能被盗,IP地址可能被伪造。没有简单的方法可以防止复杂的攻击。这种公共访问有许多您通常应该避免的权衡。尝试使用SSH作为进入非军事化区域(防火墙和代理后面的所有内容)的安全通道。这提供了一个更安全的环境,您可以在Node/Express中自行构建


希望这能有所帮助。

您控制哪台服务器?服务于8080端口的代理或其后面服务于8081端口的代理?假设,我只控制8080上的代理。感谢您的全面回答,但不幸的是,所有这些都不完全适用于这种情况。白名单的限制性太强,黑名单的限制性也不够。至于第二种解决方案,情况是我无法访问8081服务器。否则,我将能够使用某种身份验证,正如您在“开发人员访问”中提到的那样。在实际的应用程序中,考虑到它的安全缺陷,我可能会完全删除这个系统,而且我并不需要它来让我的web服务器工作。我真的只问了这个问题
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;