CSRF攻击与防御
什么是CSRF攻击
跨站请求伪造(CSRF)是指攻击者诱导用户在已认证的网站上执行非本意的操作,如转账、修改密码、发表评论等。这种攻击利用了Web应用程序对请求来源验证不足的弱点。
攻击原理
- 用户已登录目标网站,并拥有有效的会话Cookie
- 攻击者诱导用户访问恶意网站或点击恶意链接
- 恶意网站向目标网站发送请求,自动携带用户的会话Cookie
- 目标网站误以为是用户主动操作,执行相应的功能
攻击流程图示
防御措施
- 使用CSRF令牌:为每个表单请求生成唯一令牌,并在服务器端验证
- 检查Referer头部:验证请求来源是否可信
- 使用SameSite Cookie属性:限制Cookie的发送范围
- 双重提交防护:在Cookie和请求体中都包含CSRF令牌
- 自定义请求头:要求AJAX请求包含特定的自定义头部
- 验证码:在关键操作中要求用户输入验证码
Node.js防御示例
使用csurf中间件
const express = require('express');
const csurf = require('csurf');
const cookieParser = require('cookie-parser');
const app = express();
// 解析cookie
app.use(cookieParser());
// 设置CSRF保护
const csrfProtection = csurf({
cookie: true
});
// 应用CSRF中间件
app.use(csrfProtection);
// 路由
app.get('/', (req, res) => {
// 传递CSRF令牌给前端
res.render('index', { csrfToken: req.csrfToken() });
});
app.post('/submit', (req, res) => {
// CSRF令牌会自动验证
res.send('Form submitted successfully');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
React前端防御示例
在表单中包含CSRF令牌
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export default function CommentForm() {
const [csrfToken, setCsrfToken] = useState('');
const [comment, setComment] = useState('');
useEffect(() => {
// 获取CSRF令牌
axios.get('/csrf-token')
.then(res => {
setCsrfToken(res.data.csrfToken);
});
}, []);
const handleSubmit = (e) => {
e.preventDefault();
// 提交表单时包含CSRF令牌
axios.post('/submit-comment', {
comment: comment,
csrfToken: csrfToken
});
};
return (
<form onSubmit={handleSubmit}>
<input
type="hidden"
name="csrfToken"
value={csrfToken}
/>
<textarea
value={comment}
onChange={(e) => setComment(e.target.value)}
placeholder="Add a comment"
/>
<button type="submit">Submit</button>
</form>
);
}
设置SameSite Cookie属性
// Express中设置SameSite属性
app.use(cookieParser());
app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: true,
cookie: {
sameSite: 'strict', // 或 'lax'
secure: true // 在生产环境中使用HTTPS
}
}));
检测与响应
- 使用CSRF扫描工具:如OWASP ZAP、Burp Suite等
- 日志监控:记录异常请求模式,如来自不同IP但相同会话的请求
- 用户行为分析:检测异常操作,如短时间内的多次敏感操作
- 应急响应:制定CSRF攻击应急响应计划,包括撤销可疑操作和通知用户
最佳实践
- 对所有状态改变的请求实施CSRF保护
- 优先使用SameSite Cookie属性和CSRF令牌结合的防御方式
- 对敏感操作实施多因素验证
- 避免在GET请求中执行状态改变操作
- 定期进行安全测试,包括CSRF测试
- 教育用户识别钓鱼网站和恶意链接