返回 Access-Control-Allow-Origin: * 是否会削弱 JSON GET 响应的安全性?

信息安全 csrf oauth 同源策略 json 科尔斯
2021-09-03 06:34:35

W3C CORS 建议指出

某些类型的资源不应尝试指定特定的授权来源,而是拒绝或允许所有来源。

...

3. 一个 GET 响应,其实体主体恰好被解析为 ECMAScript 可以返回一个值为“*”的 Access-Control-Allow-Origin 标头,前提是没有敏感注释,因为它可以使用 HTML 脚本元素跨域访问。如果需要,这些资源可以实现如上所述的访问控制和 CSRF 保护。

JSON 是否解析为 ECMAScript?

JSON 在通过 HTML 脚本元素执行时会产生副作用吗?

跨域 Web 内容能否从通过 HTML 脚本元素伪造的 CSRF 请求中获得对 JSON GET 响应的读取权限?

在这种情况下,“敏感评论”是什么意思?

本段是否适用于不接受 cookie 或 HTTP 身份验证进行授权的 GET 请求?例如,如果请求仅由 OAuth 授权,则浏览器将无法通过 HTML 脚本元素访问其响应。但是,通过将Access-Control-Allow-Origin: *所有授权请求的响应都包含在内,服务器将失去指定浏览器授予访问权限的来源的能力。

不会包括Access-Control-Allow-Origin: *削弱对 cookie 或 HTTP Authentication 授权的请求的响应的安全性吗?例如,如果请求是由 cookie 授权的,则它可以由浏览器执行,但响应正文中的源代码将无法访问跨域 Web 内容。通过使其响应 include Access-Control-Allow-Origin: *,服务器将与浏览器通信,来自所有来源的 Web 内容除了执行响应外,还应该有权读取响应。

1个回答

你已经明白了这一点:这里的主要思想是脚本元素 ( <script src="http://example.com/myscript.js">) 不受同源限制。因此,站点可以加载任何脚本 URL 并执行该脚本(只要该脚本不需要凭据或浏览器具有访问该脚本所需的凭据)。但是,浏览器无法读取<script>元素中加载的脚本。

您可以将 W3C 的建议改写为:

如果资源中的所有信息都可以通过将资源作为脚本运行来获取,那么您可以自由添加Access-Control-Allow-Origin: *.

因此,原始 JSON 不满足此要求。如果执行脚本:

(["foo", 5, 7])

然后不会向执行环境添加任何信息。(几年前,它可以通过重新定义Array构造函数来实现,但现代浏览器已经消除了这个漏洞。)

然而,剧本

window.secrets = ["foo", 5, 7];

确实对执行环境产生了可观察到的变化。您也可以允许任何页面通过 Ajax 获取资源的内容,因为它不包含页面无法通过在<script>元素中运行脚本来学习的信息。

短语“敏感注释”指的是实际的 JavaScript 代码注释 ( /* e.g., like this */)。注释在<script>执行中是不可读的,但在通过 Ajax 访问脚本内容时它们是可读的。例如,脚本:

// by the way, the fourth secret is "bar"
window.secrets = ["foo", 5, 7]

在标签中执行时会泄漏与上一个示例相同的信息<script>,因为注释仅在查看实际脚本文本时可见。

如果资源需要 OAuth 凭据并且不接受 cookie 凭据,则第 4 节指出:

请求应该设置省略凭据标志,并且资源应该使用请求内容中明确提供的安全令牌执行授权

通过 HTML 脚本元素的跨域请求永远​​不会包含 OAuth 凭据,并且无论响应Access-Control-Allow-Origin标头的值如何,这些请求都将无法授权。

如果资源需要凭据和预检,则预检响应也必须与Access-Control-Allow-Credentials: true. 如果服务器不发送该标头,则站点无法发送跨域凭据请求来读取脚本内容。因此,Access-Control-Allow-Origin: *不会削弱受凭据保护的资源的安全性,因为目标域的凭据不会通过 Ajax 发送,除非服务器也设置Access-Control-Allow-Credentials: true.

如果资源需要凭据但不需要预检,则凭据将在服务器有机会包含Access-Control-Allow-Credentials: true在响应中之前在请求中发送。最终结果是相同的——浏览器不会与发出请求的跨域 Web 内容共享响应——但原因不同。

第 6.1 节说:

字符串“*”不能用于支持凭据的资源。

资源共享检查将通过第 7.2 节的第 2 步,并在第 3 步失败:

  1. 如果 Access-Control-Allow-Origin 标头值为“*”字符并且设置了省略凭据标志,则返回 pass 并终止此算法。
  2. 如果 Access-Control-Allow-Origin 的值与其规范定义的 Origin 标头的值不区分大小写匹配,则返回失败并终止该算法。