什么是CSRF攻击?
CSRF (Cross-site request forgery) 跨站请求伪造是一种常见的网络攻击方式。攻击者诱导用户访问已被攻击者控制的网页时,利用用户在被攻击网站已经获取的注册凭证,绕过后台的用户验证,冒充用户对被攻击的网站发起某种操作。
CSRF攻击的特点
- 依赖用户已登录目标网站
- 利用目标网站对用户浏览器的信任
- 欺骗用户的浏览器发送HTTP请求给目标网站
- 攻击一般发生在第三方网站上
防护措施
1. 验证 HTTP Referer 字段
javascript
// 服务器端验证 Referer
const referer = ctx.request.headers.referer;
if (!referer || !referer.startsWith('https://trusted-domain.com')) {
ctx.throw(403, 'Invalid referer');
}
优点:
- 实现简单
- 兼容性好
缺点:
- Referer 可能被篡改
- 某些浏览器可能会禁用 Referer
2. 添加 CSRF Token
javascript
// 生成 token
const token = crypto.randomBytes(24).toString('hex');
// 在表单中嵌入 token
<input type="hidden" name="_csrf" value="<%= token %>">
// 服务器端验证
if (req.body._csrf !== req.session.csrf) {
return res.status(403).json({ message: 'Invalid CSRF token' });
}
优点:
- 安全性高
- 完全可控
缺点:
- 需要在每个表单中添加 token
- 增加了开发成本
3. 使用 SameSite Cookie 属性
javascript
// 设置 Cookie
res.cookie('sessionId', 'abc123', {
sameSite: 'Strict', // 或 'Lax'
secure: true
});
优点:
- 配置简单
- 浏览器原生支持
缺点:
- 浏览器兼容性问题
- 可能影响某些正常的跨站请求
4. 双重 Cookie 验证
javascript
// 在页面中通过 JavaScript 读取 cookie 中的 csrf_token
const csrfToken = document.cookie.match(/csrf_token=(.*?);/)[1];
// 将 token 添加到请求头
fetch('/api/data', {
headers: {
'X-CSRF-Token': csrfToken
}
});
最佳实践建议
- 组合使用多种防护措施
- 对重要操作使用验证码或二次确认
- 使用 HTTPS 确保传输安全
- 定期更新 CSRF Token
- 合理设置 Cookie 的作用域和有效期
示例代码:Express 中间件实现 CSRF 防护
javascript
const express = require('express');
const csrf = require('csurf');
const cookieParser = require('cookie-parser');
const app = express();
// 解析 Cookie
app.use(cookieParser());
// 启用 CSRF 防护
app.use(csrf({ cookie: true }));
// 错误处理
app.use((err, req, res, next) => {
if (err.code === 'EBADCSRFTOKEN') {
res.status(403);
res.send('CSRF 验证失败');
} else {
next(err);
}
});
// 在表单中注入 token
app.get('/form', (req, res) => {
res.send(`
<form action="/submit" method="POST">
<input type="hidden" name="_csrf" value="${req.csrfToken()}">
<button type="submit">提交</button>
</form>
`);
});
总结
CSRF 攻击虽然危害严重,但通过合理的防护措施可以有效预防。选择合适的防护方案时需要考虑:
- 系统的安全需求级别
- 开发维护成本
- 用户体验影响
- 浏览器兼容性
建议在实际项目中采用多层防护机制,并根据具体场景选择最适合的防护措施组合。