在 localhost 上启用 cors 有什么安全风险?

信息安全 javascript 访问控制 科尔斯
2021-08-30 02:30:36

我有一个基于 Cordova 的移动应用程序,它通过移动设备上的本地服务器访问一些 API。移动应用程序将来源设置为 Localhost。这里 cors 开始了,我无法提出请求。现在这些 API 可以通过终端、邮递员和其他非浏览器环境使用,而不会触发 CORS。

现在在这种情况下,在 localhost 上启用 cors 有什么风险?只是为了澄清我想在生产中将 localhost 的 cors 列入白名单。

2个回答

答案实际上取决于您创建的 API 及其工作方式。 这个网站对CORS的好坏给出了很好的解释。简而言之,作者创建了一个虚构的 API,用于从另一个域发送电子邮件。他说:

如果您使用基于会话 cookie 的身份验证,您可能不应该允许所有人的 CORS 请求。恶意网站可以在未经用户特定许可的情况下通过 AJAX 请求向 api.yoursebsite.com 发出电子邮件发送请求。

这是(在他的假设情况下)“启用 cors 的风险是什么”这个问题的答案?在这种情况下,他还提供了有关如何考虑缓解的更多信息:

如果用户在他们的浏览器中有有效的会话 cookie,它们将用于在 api.yoursebsite.com 上进行身份验证,这将导致不需要的电子邮件发送。在大多数情况下,危险请求将被“预检”,这意味着域需要在他们甚至可以发送请求之前获得批准。这将防止任何恶意活动的发生。

这(以一种稍微隐蔽的方式)说明了 dandavis 已经说过的话:CORS 与安全性没有太大关系。安全性在服务器端完成。无论如何,黑客都不会遵守 SOP。

在您的情况下,据我了解,您想通过 CORS 将 localhost 启用为域,以便可以通过某个不同的域发出请求?如果这是正确的,我认为您将不会面临真正的安全问题在您打开一些仅绑定到环回地址(localhost)的套接字的前提下,某人能够访问它的唯一方法(以恶意或其他方式)将是:他已经可以访问环回地址。这意味着:他已经获得了对设备的访问权限。

基于 Conor Mancone 非常正确的评论:CORS 主要防止未经授权的读取请求。它不能保护服务器免受写入或触发未经授权的操作。这必须通过授权概念来实施。

不,这不是(必然)安全的。其他答案大多是正确的,除了他们做了两个(常见但不正确的)假设:本地主机始终是 127.0.0.1,并且在您的机器上运行的网络服务器是您想要运行的。这些不是安全的假设

一些机器,由于出于某种目的故意修改或仅仅因为 HOSTS 文件最小(或丢失),没有将 localhost 定义为 127.0.0.1(或 IPv6 的 ::1),因此对该名称进行 DNS 查找。DNS当然通常不安全;同一网络上的攻击者(或您和愿意权威说明“localhost”映射到什么 IP 地址的 DNS 服务器之间的任何地方)可以注入指定他们自己的 IP 地址的 DNS 回复。然后,您的应用会从攻击者的 Web 服务器加载 Web 内容。攻击者可以向受害者发送恶意 Web 内容,窃取您的服务的信用,从您的帐户中窃取内容,恶意滥用您的帐户,使用 JS-to-native API 桥来攻击您的设备(或至少恶意访问移动设备的数据)应用程序可以看到),等等。

好的,那么如果你使用“127.0.0.1”而不是“localhost”呢?IP 地址永远不需要通过 DNS,127.0.0.1 总是被路由到你自己的机器上,你应该没问题,对吧?

还是个坏主意!TCP 套接字不尊重用户之间(或沙盒应用程序之间)的权限隔离。如果您的移动用户有一个在该端口上运行网络服务器的粗略应用程序,您的应用程序将连接到恶意服务器,而不是连接到您的应用程序尝试启动的服务器(这将无法绑定套接字,因为它已经在使用中)。您几乎可以肯定也可以将其放入应用商店;它没有使用任何不允许的 API 或任何东西,只是在绑定到特定端口的环回套接字上提供 Web 内容(与您相同)。同样在服务器/台式机/笔记本电脑上,如果您的机器允许非管理员远程访问(通过 SSH、远程桌面等),那么其中一个用户可能会在您使用的端口上启动恶意 Web 服务器,然后等待您的应用程序连接到它。

当然,即使没有任何恶意尝试,这整个想法也只是脆弱的。正如我上面提到的,不能保证没有其他进程在您选择的同一端口上运行 Web 服务器。其中只有 2^16 个可供选择,对于某些范围,操作系统本身可能会随机将出站连接绑定到该端口,以便客户端应用程序(如 Web 浏览器)而不是服务器使用它。无论哪种方式,用于提供您的 Web 内容的服务器将无法绑定端口,您的应用程序将无法与其期望的服务器通信,并且您的用户将获得糟糕的体验。


请注意,这与 CORS 无关。无论您从哪个来源加载内容,您的服务器都需要允许该来源查看 Web 响应。

重要的一点是要确保安全地加载 Web 内容,而通过普通 TCP 的 HTTP(即,没有 TLS 或其他方式来验证和保护连接)并不安全!


解决方案:只需从面向 Internet 的 Web 服务器加载内容(通过 HTTPS)。然后,您的应用程序不需要通过 HTTP 加载任何内容,您的 Web 服务不需要允许来自通过 HTTP 加载的任何网页的任何请求,并且应用程序可以确保它从正确的服务器加载内容。

您甚至可以提供来自同一个域的内容,因此甚至不需要跨域(即 CORS)请求!只需使用老式的 XMLHttpRequests(或 Fetch,没有 CORS)并从 Web 服务中删除任何与 CORS 相关的内容。


讲故事的时间:

我工作的前一家公司有一个产品,它做了你所描述的事情——将数据从本地主机网络服务器加载到网络视图中——我们遇到了一个非常有趣的问题,有些人报告说网络视图是公正的。 .. 空的。无内容。本地服务器正在运行,内容已正确打包和安装,webview 正在尝试发出 web 请求……但似乎服务器没有响应。长话短说,我们最终将其追溯到那些机器上未定义的“localhost”。这只是大约 10,000 名用户中的少数(在 Mac 上,因为这是运行我们应用程序的唯一平台),但我们停止使用“localhost”已经足够了。当然,正如我上面解释的,“127.0.0.1”也不是安全的,