Web应用中的CSRF防护机制

什么是CSRF攻击?

CSRF (Cross-site request forgery) 跨站请求伪造是一种常见的网络攻击方式。攻击者诱导用户访问已被攻击者控制的网页时,利用用户在被攻击网站已经获取的注册凭证,绕过后台的用户验证,冒充用户对被攻击的网站发起某种操作。

CSRF攻击的特点

  1. 依赖用户已登录目标网站
  2. 利用目标网站对用户浏览器的信任
  3. 欺骗用户的浏览器发送HTTP请求给目标网站
  4. 攻击一般发生在第三方网站上

防护措施

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
  • 增加了开发成本
javascript 复制代码
// 设置 Cookie
res.cookie('sessionId', 'abc123', {
  sameSite: 'Strict',  // 或 'Lax'
  secure: true
});

优点:

  • 配置简单
  • 浏览器原生支持

缺点:

  • 浏览器兼容性问题
  • 可能影响某些正常的跨站请求
javascript 复制代码
// 在页面中通过 JavaScript 读取 cookie 中的 csrf_token
const csrfToken = document.cookie.match(/csrf_token=(.*?);/)[1];

// 将 token 添加到请求头
fetch('/api/data', {
  headers: {
    'X-CSRF-Token': csrfToken
  }
});

最佳实践建议

  1. 组合使用多种防护措施
  2. 对重要操作使用验证码或二次确认
  3. 使用 HTTPS 确保传输安全
  4. 定期更新 CSRF Token
  5. 合理设置 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 攻击虽然危害严重,但通过合理的防护措施可以有效预防。选择合适的防护方案时需要考虑:

  • 系统的安全需求级别
  • 开发维护成本
  • 用户体验影响
  • 浏览器兼容性

建议在实际项目中采用多层防护机制,并根据具体场景选择最适合的防护措施组合。

相关推荐
腾讯TNTWeb前端团队3 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰6 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪7 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪7 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy7 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom8 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom8 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom8 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom8 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom8 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试