http - 使用浏览器缓存的跨站点攻击(会起作用吗?)
问题描述
攻击方案:被攻击站点使用 cookie 发出请求(但没有Vary: Cookie
HTTP 标头),浏览器缓存响应,攻击站点发出相同的请求(但没有 cookie,因为使用SameSite=Strict
了指令 in Set-Cookie
)并访问缓存的响应。我一定错过了什么,或者它可以工作吗?
更新:我做了一些实验:
快递服务器:
const express = require('express')
const app = express()
const port = 3000
app.get('/token', (req, res) => {
let secret = "No access";
if (req.headers['cookie'] && req.headers['cookie'].includes('token=1234')) {
secret = '1234';
}
res.set({
'Set-Cookie': 'token=1234; Path=/; Max-Age=2592000; HttpOnly; SameSite=Strict',
'Access-Control-Allow-Origin': '*',
'Content-Type': 'text/plain',
'ETag': secret,
// 'Vary': 'Cookie',
'Cache-Control': 'max-age=1000',
});
res.send(secret);
})
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
被攻击和攻击者index.html
:
<!DOCTYPE html>
<html>
<body>
<div></div>
<script>
fetch('http://localhost:3000/token').then(function(response) {
return response.text();
}).then(function(text) {
document.querySelector('div').textContent = text;
});
</script>
</body>
</html>
localhost:3000
正如预期的那样,向我展示了令牌(当然是在第二次加载之后)。为了创建攻击者,我将 HTML 上传到https://jsfiddle.net/3xaoe4zf/。它适用于 Chromium 84!(即 jsfiddle 显示了令牌),但在 Firefox 78 中没有。有人可以解释这种差异吗?
解决方案
这种攻击似乎有效(至少在 Chromium 84 中),并Vary: Cookie
阻止了它。
但它在 Firefox 中不起作用,因为它出于某种原因为这两个站点存储了一个单独的缓存(它可能使用Origin
或类似的东西作为缓存的额外键)。(请注意:当使用 F5 重新加载页面时,Firefox 不使用缓存。)
这不是 Chromium/Chrome 问题,只是缓存以这种方式工作。
根据规范:
主缓存键由请求方法和目标 URI 组成。
此外,在同一部分中,它指出Vary
可以使用辅助键(使用 ):
如果请求目标接受内容协商,则其缓存条目可能包含多个存储的响应,每个响应由原始请求的选择标头字段的值的辅助键进行区分(第 4.1 节)。
对于使用 cookie 接收的响应,我在规范中没有发现任何具体限制。
推荐阅读
- excel - 来自另一个 Excel 工作表中标识的标题的动态列引用
- npm - NPM 运行观察退出状态 3221226505
- django - GraphQL - JWT - 更改 verifyToken 突变的有效负载 - django
- ios - UIWebview 中的嵌套 stringByEvaluatingJavaScript 迁移到 WKWebview
- java - JSTL - 春季启动
- flutter - 使用 ConstrainedBox 和 Container 小部件为其子框提供约束有什么区别?
- angular - ngIf 和 ngFor 在 Ionic 5 (Angular 9) 组件中不起作用
- angular - 如何使用 AGM 向 Google 地图添加图例
- python - “testpymunk.py”,第 3 行,在
import pymunk # Import pymunk.. ModuleNotFoundError: No module named 'pymunk' - c# - C# 在没有 CryptoStream 的情况下使用 SymmetricAlgorithm