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的防护策略分为三步:
- 将token输出到页面 首先,用户打开页面的时候,服务器需要给这个用户生成一个Token,该Token通过加密算法对数据进行加密,一般Token都包括随机字符串和时间戳的组合,显然在提交时Token不能再放在Cookie中了,否则又会被攻击者冒用。
- 请求中携带token
- 服务端验证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 头部,如何处理?
3. SameSite Cookie
- 什么是 SameSite Cookie 属性?有哪些取值?
- 如何利用 SameSite 防御 CSRF?
- SameSite 的限制是什么?在兼容性上是否有问题?
4. 双重提交 Cookie(Double Submit Cookie)
- 什么是双重提交 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 漏洞频发,你会如何推动改进?