将所有域添加到 CORS(访问控制允许源:*)的安全隐患

Security implications of adding all domains to CORS (Access-Control-Allow-Origin: *)

本文关键字:许源 安全 访问控制 添加 CORS      更新时间:2023-09-26
据说

,与其将所有域添加到CORS中,不如只添加一组域。然而,添加一组域有时并非易事。例如,如果我想公开一个API,那么对于每个想要调用该API的域,都需要联系我以将该域添加到允许的域列表中。

我想在安全影响和减少工作量之间做出有意识的权衡。

我看到的唯一安全问题是DoS攻击和CSRF攻击。CSRF 攻击已经可以通过 IMG 元素和 FORM 元素来实现。与 CORS 相关的 DoS 攻击可以通过阻止反向链接标头上的请求来克服。

我是否遗漏了安全隐患?


===编辑===

  • 假定未设置Access-Control-Allow-Credentials标头
  • 我知道如何添加给定的域列表"CORS 访问",因此我只对添加所有域"CORS 访问"的安全影响感兴趣

跨站点请求伪造攻击无疑是访问控制允许源解决的主要问题。

Ryan在内容检索方面当然是正确的。但是,关于提出请求的问题,这里还有更多要说的。许多网站现在都提供 RESTful Web 服务,这些服务公开了可能涉及在后端进行重大更改的各种功能。通常,这些 RESTful 服务旨在使用 XHR(例如 AJAX(请求(可能以"单页应用程序"作为前端(调用。如果用户在访问恶意第三方站点时具有授予对这些服务的访问权限的活动会话,则该站点可能会尝试在后台调用这些 REST 终结点,并传入可能危及用户或站点的值。根据 REST 服务的定义方式,有多种方法可以防止这种情况发生。

在单页应用的 REST Web 服务的特定情况下,您可以规定对后端 REST 终结点的所有请求都是使用 XHR 发出的,并拒绝任何非 XHR 请求。您可以通过检查是否存在自定义请求标头(类似于jQuery的X-Request-With(来指示这一点。只有 XHR 类型的请求才能设置这些标头;来自表单和嵌入式资源的简单 GET 和 POST 请求不能。最后,我们想要决定 XHR 请求的原因让我们回到了最初的问题 - XHR 请求受 CORS 规则的约束。

如果您允许Access-Control-Allow-Origin: *,则任何站点都可以代表用户向 REST 端点发出任何 AJAX 请求。如果您的 REST 端点涉及任何类型的敏感数据或允许数据持久性,则这是一个不可接受的安全漏洞。相反,像我描述的那样强制执行仅限 XHR 的请求,并定义允许发出这些请求的来源白名单。

值得指出的是,如果您的 REST 端点不公开任何敏感信息,或者它们不允许用户进行任何持久数据更改,那么Access-Control-Allow-Origin: *可能是合适的决定。例如,谷歌地图提供公共地图数据的只读视图;没有理由限制可能希望调用这些服务的第三方网站。

老问题,但这里有很多不好的答案,所以我必须添加我的。

如果未设置 Access-Control-Allow-Credentials ,并且执行无 cookie 身份验证(即调用方提供持有者授权标头(,则无需将源列入白名单。 只需在Access-Control-Allow-Origin中呼应原点.

结构良好的 REST API 可以从任何源安全地调用。

您可以发送多个,例如:

Access-Control-Allow-Origin: http://my.domain.com https://my.domain.com http://my.otherdomain.com

但我建议不要这样做。相反,请保留允许域的白名单。比方说:

allowed = [ "X", "Y", "A.Z" ];

然后,如果您收到来自X的请求,请回复:

Access-Control-Allow-Origin: X

如果您收到来自A.Z的请求,请回复:

Access-Control-Allow-Origin: A.Z

如果从不允许的域收到请求,请使用错误或无 CORS 策略进行响应。

所有 XHR 请求都将发送一个 Origin 标头,因此请使用它。而且,您只需发送OPTIONS请求的 CORS 策略标头,而无需发送随后的GET/POST/HEAD请求。


我看到的主要问题是你暴露了所有的域。也许您有一个安全的管理域,例如:https://admin.mydomain.com,或者您有一个尚未准备好启动的产品网站。您不希望包含手头请求并非绝对必要的任何内容。

*只是非常懒惰。


CORS是关于获取内容,而不仅仅是提出请求。当您通过 img 或脚本标签获取资源时,您可以欺骗某人的浏览器发出 CSRF 样式的请求。这是正常的,您可以使用普通的CSRF令牌来防止这种情况。

在所有域上启用 CORS 后,您现在可以让攻击站点上的 javascript 发出请求并取回内容,从而侵犯他们的隐私。

例:

想象一下,您的背部为所有域启用 CORS。现在我做了一个网站,要求 yourimaginarybank.com/balance

IMG请求不会做任何事情,因为我的javascript无法获取您银行网站上该页面的html中的内容。现在他们已经打开了 CORS,我网站上的 javascript 实际上会返回一个包含您的余额的 HTML 页面,并将其保存到我的服务器。我不仅可以像以前一样发出GET请求,而且现在我可以看到里面的内容。这是一个巨大的安全问题。

如何在不向标题中添加大列表的情况下解决问题?每个 CORS 请求都是使用源标头发出的。最好的解决方案可能是读取 Origin 标头,然后查询数据库以查看它是否像 Fritz 在他的答案中建议的那样被列入白名单。

除了csauve的回答,没有一个回答我原来的问题。

回答我的问题;似乎只要没有设置Access-Control-Allow-Credentials,就没有安全问题。

(这让我想知道为什么规范要求在未设置Access-Control-Allow-Credentials时进行预检?

最佳做法是首先检查传入请求的域,然后生成响应标头。根据是否允许此域发送请求,将其(仅此域(添加到Access-Control-Allow-Origin响应标头。

Afaik,甚至不可能向此标头添加多个域。所以它要么是*,要么是一个特定的域,我总是不想添加*