为了防止跨站请求伪造(Cross-Site Request Forgery, CSRF)攻击,前端开发中可以采取以下几种常见安全措施:
这是最常用的防御机制之一。
生成Token: 用户登录后,服务器生成一个随机的、不可预测的CSRF Token,并将其存储在服务器端,同时通过Set-Cookie头部发送给客户端,存储在用户的Cookie中。
表单嵌入Token: 在每个需要防护的HTML表单中,添加一个隐藏字段(),其值设置为从Cookie中读取的CSRF Token。
验证Token: 当表单提交时,后端会接收到表单数据以及Cookie中的Token(由于同源策略,浏览器会自动发送Cookie)。服务器端验证表单中的Token与存储在服务器端或Session中的Token是否一致。如果不一致,则拒绝请求。
虽然不是完全可靠,因为Referer和Origin可能被篡改或缺失,但在某些场景下仍可作为一种辅助手段。
检查Referer: 验证HTTP请求头中的Referer字段,确保请求是从预期的域名发起的。但需注意,这种方法有局限性,比如在HTTPS到HTTP的降级请求中,Referer不会被发送。
检查Origin Header: 类似于Referer,Origin header提供了请求来源的信息,但只在使用XMLHttpRequest或Fetch API时发送。
对于那些不需要跨站访问的Cookie,可以设置SameSite属性以增强安全性。
在AJAX请求中添加一个自定义的HTTP头(如X-Requested-With: XMLHttpRequest
),然后在服务器端验证这个头的存在和值。因为JavaScript可以自由设置XMLHttpRequest的头,而普通表单提交做不到,这可以区分出由脚本发起的请求。
服务器端(伪代码):
// 生成并设置Token
function generateCsrfToken() {
return crypto.randomBytes(32).toString('hex');
}
app.post('/login', (req, res) => {
const token = generateCsrfToken();
res.cookie('csrfToken', token, { httpOnly: true, secure: true, sameSite: 'strict' });
// 存储token到session或其他存储机制
});
app.post('/submitForm', (req, res) => {
if (req.body.csrfToken === req.cookies.csrfToken) {
// 请求合法,处理逻辑...
} else {
// CSRF攻击检测,拒绝请求
res.status(403).send('Forbidden');
}
});
前端HTML:
<form action="/submitForm" method="POST">
<input type="hidden" name="csrfToken" value="{{csrfToken}}">
<button type="submit">Submitbutton>
form>
请注意,上述代码仅为示例,实际应用中需要根据使用的后端框架和语言进行调整。