我正在阅读Mozilla上的子源完整性[1]。他们分析了下面的代码片段,并写下了以下内容:
匿名值意味着浏览器应该省略用户可能与域关联的任何cookie或身份验证这样可以防止跨源数据泄漏,同时也可以减少请求
<script src="https://code.jquery.com/jquery-2.1.4.min.js"
integrity="sha384-R4/ztc4ZlRqWjqIuvf6RX5yb/v90qNGx6fS48N0tRxiGkqveZETq72KgDVJCp2TC"
crossorigin="anonymous"></script>
我很感兴趣的是为什么这样可以防止跨源数据泄漏[2]。Mozilla编写了以下内容:
攻击者会尝试加载具有已知摘要的资源,并注意加载失败如果加载失败,攻击者可以推测响应与哈希不匹配,从而深入了解其内容。例如,这可能会显示用户是否登录到特定服务。
我了解如何使用integrity
属性来显示资源的内容。如果内容依赖于客户端,这似乎很有趣。然而,我不明白两件事:
- 如果某个特定客户端加载某个资源时,恰好黑客对该资源的内容感兴趣,并且黑客可以控制该页面上的HTML和Javascript。那么,为什么黑客会试图通过使用完整性哈希来揭示所述资源的内容,为什么不直接从客户端获取资源并将
responseText
发送到恶意网站呢?当然,除非CORS阻止这种情况,但CORS似乎和其他请求一样阻止SRI[3] - Mozilla似乎描述了网站所有者需要将CCD_ 3设置为CCD_;bruteforce";页面信息通过暴力哈希?如果黑客可以控制页面上的
integrity
属性,那么在大多数情况下他们也可以控制crossorigin
属性,那么为什么这很重要呢
您描述的情况与该文档的作者所想的不同。攻击者可能对子资源加载触发的已验证请求的响应的确切内容不感兴趣;相反,攻击者可能只是想从恶意来源确定受害者是否登录到目标。
想象一种情况,其中对GET
和https://example.com/1.js
的响应取决于请求是否携带某种身份验证cookie(为了简单起见,此处标记为SameSite=None; Secure
(:
alert('authenticated');
或
alert('anonymous');
alert('anonymous');
的SHA-256(后面跟一个换行符(是a7c873e2f388c05f57d1245cfa0c20e4bf5b064677ba4f959c5dd53668590339
。攻击者可以设置以下恶意页面,该页面将充当登录预言机:
<script integrity="sha256-a7c873e2f388c05f57d1245cfa0c20e4bf5b064677ba4f959c5dd53668590339"
src="https://example.com/1.js"
crossorigin="use-credentials"
onerror="notifyAttackerVisitorIsLoggedInToExampleDotCom();">
当受害者访问攻击者的恶意页面时,可能出现两种情况:
- 如果受害者未登录到
https://example.com
,则对子资源加载的响应包含alert('anonymous');
,其哈希值与攻击者的integrity
属性中指定的值匹配。没有出现错误 - 如果受害者登录到
https://example.com
,则对子资源加载的响应包含alert('authenticated');
,其哈希值与攻击者的integrity
属性中指定的值不匹配。因此,会发生错误,onerror
事件侦听器会启动,从而通知攻击者