什么是CSRF 攻击

CSRF(Cross-Site Request Forgery,跨站请求伪造)攻击是一种网络攻击手段,它利用合法用户的权限来执行非授权的操作。攻击者通过伪装成合法用户向Web应用程序发送请求,从而执行非预期的操作,如更改密码、转账等。CSRF攻击之所以能够成功,是因为攻击者可以利用用户的登录状态来发送请求,而服务器无法区分这些请求是由合法用户还是攻击者发起的。

CSRF攻击的工作原理

  1. 用户登录

    • 用户登录到一个网站,并且浏览器保存了网站的Cookie。
  2. 攻击者构建恶意链接

    • 攻击者构建一个包含恶意请求的URL,这个请求指向受害者的账户所在网站,并且包含一些预定义的操作,如转账、更改邮箱地址等。
  3. 用户点击恶意链接

    • 用户在不知情的情况下点击了包含恶意请求的URL。此时,用户的浏览器会自动附带上先前保存的Cookie(因为Cookie是自动发送的)。
  4. 请求发送到服务器

    • 包含恶意请求的HTTP请求被发送到了受害者的账户所在的网站,由于请求包含了正确的Cookie,所以服务器认为这是合法用户的请求。
  5. 服务器执行请求

    • 服务器根据请求的内容执行了相应的操作,如转账等。

如何防御CSRF攻击

防御CSRF攻击的关键是在服务器端采取措施,确保请求是用户主动发起的,而不是被恶意链接触发的。以下是一些常用的防御策略:

  1. 使用CSRF Token

    • 在表单中加入一个隐藏字段,包含一个随机生成的token。这个token应该在服务器端生成并在用户会话开始时存储在session中。每次提交表单时,都要求客户端提供这个token,并在服务器端验证这个token的有效性。
    html 复制代码
    <form action="/transfer" method="post">
      <input type="hidden" name="_csrf" value="some-random-token">
      <!-- 其他表单字段 -->
      <button type="submit">Transfer</button>
    </form>
  2. 验证Referer头

    • 服务器端可以检查HTTP请求的Referer头,确保请求来自预期的页面。但是这种方法并不总是可靠,因为Referer头可以被伪造。
  3. 双因素认证

    • 对于敏感操作,可以要求用户进行二次确认,如输入手机验证码、使用硬件令牌等。
  4. 限制请求频率

    • 对于特定的API端点,可以限制请求的频率,超出限制则拒绝服务。
  5. 使用HTTP-only Cookie

    • 设置HTTP-only标志,使得Cookie不能通过JavaScript访问,减少攻击面。
  6. SameSite Cookie属性

    • 使用SameSite属性来限制Cookie仅在原站点上下文内发送。设置SameSite=StrictSameSite=Lax可以帮助防止CSRF攻击。
  7. 教育用户

    • 提醒用户不要随便点击不明链接或附件,提高用户的网络安全意识。

示例:使用CSRF Token

假设你正在使用Node.js和Express框架构建一个Web应用,可以使用如下代码来实现CSRF防护:

javascript 复制代码
const express = require('express');
const csrf = require('csurf');
const session = require('express-session');

const app = express();
app.use(express.urlencoded({ extended: false }));
app.use(session({ secret: 'secret', resave: false, saveUninitialized: false }));
app.use(csrf()); // 使用CSRF中间件

app.use((req, res, next) => {
  res.locals.csrfToken = req.csrfToken(); // 将CSRF token传递给前端
  next();
});

app.get('/login', (req, res) => {
  res.render('login');
});

app.post('/login', (req, res) => {
  // 登录逻辑
});

app.get('/transfer', (req, res) => {
  res.render('transfer', { csrfToken: req.csrfToken() }); // 在模板中包含CSRF token
});

app.post('/transfer', (req, res) => {
  const { amount, csrf } = req.body;
  // 验证CSRF token
  if (!req.csrfToken(csrf)) {
    return res.status(403).send('Invalid CSRF token');
  }
  // 转账逻辑
  res.send('Transfer successful');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

通过以上措施,可以有效地减轻CSRF攻击的风险。然而,任何安全措施都不是绝对的,因此需要综合多种手段来提高系统的安全性。

相关推荐
橙子家2 小时前
浏览器缓存之【身份与会话管理】:Cookies 和 Private state tokens
前端
最新资讯动态3 小时前
HDC 2026 | 对话鲸鸿动能:存量时代,品牌如何夺回营销“主动权”?
前端
最新资讯动态3 小时前
游戏出海,从产品走向体系
前端
最新资讯动态3 小时前
20人团队跑出百万DAU、大厂也来抢量:谁在鸿蒙生态跑出加速度
前端
最新资讯动态3 小时前
千万开发者背后,鸿蒙商业化的B面
前端
爱勇宝5 小时前
AI 时代:智商决定起点,情商决定走多远
前端·ai编程
kyriewen5 小时前
用了半年 Claude Code 后,我尝试关掉它写了一周代码——结果比想象中严重
前端·javascript·ai编程
IT_陈寒6 小时前
Vite的静态资源打包让我熬夜到三点,这坑千万别跳
前端·人工智能·后端
徐小夕7 小时前
万字拆解 JitWord:企业级实时协同文档底层架构 + 大模型 AI 融合完整实践
前端·vue.js·github
一份执念7 小时前
uni-app 小程序分包限制处理与主包体积优化实战
前端·微信小程序