CSRF是什么

CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求,利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

一个典型的CSRF攻击有着如下的流程:

  • 受害者登录a.com,并保留了登录凭证(Cookie)。
  • 攻击者引诱受害者访问了b.com。
  • b.com 向 a.com 发送请求。
  • a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
  • a.com以受害者的名义执行了这个请求。
  • 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作。

CSRF的特点

  • 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生
  • 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据
  • 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”
  • 跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等。

如何进行预防

CSRF通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对CSRF的防护能力来提升安全性。

防止csrf常用方案如下:

  • 阻止不明外域的访问
  • 同源检测
  • Samesite Cookie
  • 提交时要求附加本域才能获取的信息
  • CSRF Token
  • 双重Cookie验证

同源检测

Cookie的同源和浏览器的同源策略有所区别:

  • 浏览器同源策略:协议、域名和端口都相同即同源;
  • Cookie同源策略:域名相同即同源;

在HTTP协议中,每个异步请求都会携带两个header,用来标记来源域名:

  • Origin Header
  • Referer Header

这两个Header在浏览器发起请求时,大多数情况会自动带上,并且不能由前端修改,服务器接收到后可以根据这两个Header确定来源的域名;

综上所述: 同源验证是一个相对简单的防范方法,能够防范绝大多数的CSRF攻击。但这并不是万无一失的,对于安全性要求较高,或者有较多用户输入内容的网站,我们就要对关键的接口做额外的防护措施。

Samesite Cookie属性

Chrome 51版本后,浏览器的 Cookie 新增加了一个SameSite属性,用来防止 CSRF 攻击。

Cookie的Samesite属性用来限制第三方Cookie, 从而减少安全风险,它有三个值:

  • Set-Cookie: SameSite = Strict;
  • Set-Cookie: SameSite = Lax;
  • Set-Cookie: SameSite = None;

Strict: 最为严格,完全禁止第三方Cookie, 跨站点时,任何情况都不发送Cookie;

Lax: 限制稍微宽松,大多数情况下时不发送第三方Cookie的,除了a链接、预加载请求和GET表单;

None: 关闭SameSite属性,但必须同时设置Secure属性,

CSRF token

CSRF token的防护策略分为三步:

  1. 将token输出到页面 首先,用户打开页面的时候,服务器需要给这个用户生成一个Token,该Token通过加密算法对数据进行加密,一般Token都包括随机字符串和时间戳的组合,显然在提交时Token不能再放在Cookie中了,否则又会被攻击者冒用。
  2. 请求中携带token
  3. 服务端验证token是否正确 服务端拿到客户端给的token后,先解密token,再比对随机字符串是否一致、时间是否有效,如果字符串对比一致且在有效期内,则说明token正确。

常见考点

1. CSRF 的基本概念

问题

  • 什么是 CSRF?它的攻击流程是怎样的?
  • CSRF 和 XSS 有什么区别?在实际场景中如何区分?
  • 为什么 CSRF 攻击能够成功?需要满足哪些条件?

2. CSRF 的原理分析

问题

  • CSRF 的攻击依赖哪些机制(如浏览器的同源策略、自动携带 Cookie 等)?
  • 为什么说 CSRF 是一种“跨站”攻击?
  • 在 POST 和 GET 请求中,CSRF 的实现方式是否有区别?如果有,请详细说明。

3. CSRF 的攻击场景

问题

  • 能否举例说明 CSRF 攻击的常见场景?如恶意转账、修改用户资料。
  • 在单点登录(SSO)中,CSRF 攻击可能会带来什么危害?
  • 如果网站使用了跨域资源共享(CORS),是否会增加 CSRF 的风险?为什么?

4. CSRF 的检测

问题

  • 如何发现系统中存在 CSRF 漏洞?
  • 有哪些自动化工具可以用来检测 CSRF 漏洞?例如:Burp Suite、OWASP ZAP。
  • 在代码审查中,如何识别可能存在的 CSRF 风险?

5. CSRF 的防御方法

问题

1. CSRF Token 防御
  • 什么是 CSRF Token?它的原理是什么?
  • CSRF Token 应该如何生成和验证?
  • 在单页应用(SPA)中,如何实现 CSRF Token 的防护?
  • CSRF Token 是否可以存储在 Cookie 中?为什么?
2. Referer / Origin 检查
  • 什么是 Referer?如何通过它防御 CSRF?
  • Origin 和 Referer 有什么区别?在防御 CSRF 时,哪个更可靠?
  • 如果浏览器未发送 Referer 头部,如何处理?
  • 什么是 SameSite Cookie 属性?有哪些取值?
  • 如何利用 SameSite 防御 CSRF?
  • SameSite 的限制是什么?在兼容性上是否有问题?
  • 什么是双重提交 Cookie?它的工作原理是什么?
  • 双重提交 Cookie 与 CSRF Token 防护方法相比,有哪些优缺点?
  • 在跨域请求场景中,双重提交 Cookie 是否有效?
5. 用户验证
  • 为什么要求用户重新输入密码或验证码可以有效防御 CSRF?
  • 在什么场景下,应考虑使用用户验证来增强安全性?
6. CORS 和预检请求
  • CORS 在防御 CSRF 中能起到什么作用?
  • 如果服务端启用了 CORS 配置,如何避免意外的 CSRF 风险?

6. 实战问题与代码分析

问题

  • 如果你发现一个系统中的表单没有验证 CSRF Token,如何修复?
  • 给出一段代码,要求候选人分析是否存在 CSRF 漏洞,并提出解决方案:
app.post('/transfer', (req, res) => {
    const { to, amount } = req.body;
    // 假设这里执行了转账逻辑
    res.send('Transfer complete');
});
  • 如果在一个受信任的第三方平台中加载的 iframe 中发起跨域请求,是否可能出现 CSRF?如何防御?

7. CSRF 与现代开发的结合

问题

  • 在前后端分离的架构中,CSRF 攻击是否更容易?为什么?
  • 在使用 JWT 认证时,如何防御 CSRF?
  • 如果项目需要支持多设备登录,如何设计防御 CSRF 的机制?

8. 项目实践经验

问题

  • 你在项目中是否遇到过 CSRF 漏洞?是如何发现并修复的?
  • 哪种 CSRF 防御方法在你的实际项目中应用最多?为什么?
  • 如果团队忽略了安全性,导致 CSRF 漏洞频发,你会如何推动改进?