Scheme of the attack: Attacked site makes a request with cookies (but without Vary: Cookie HTTP header), the browser caches a response, attacking site makes the same request (but without cookies because SameSite=Strict directive in Set-Cookie was used) and gets access to the cached response. I must have missed something, or could it work?
Update: I did some experiments:
Express server:
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}`)
})
Attacked and attacker 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 as and expected shows me the token (after a second loading of course). To create an attacker I uploaded the HTML to https://jsfiddle.net/3xaoe4zf/. And it works in Chromium 84! (i.e. jsfiddle shows the token), but does not in Firefox 78.
Сan anyone explain this difference?