跨站请求伪造如何拦截

wen 开源项目 25

从原理到实战的完整防御指南

📖 目录导读

  1. 什么是跨站请求伪造(CSRF)?核心原理解析
  2. CSRF攻击的典型场景与危害
  3. 主流CSRF拦截技术详解
    • 1 同步器令牌模式(Synchronizer Token Pattern)
    • 2 同源检测(Origin/Referer验证)
    • 3 双重提交Cookie
    • 4 自定义请求头
  4. 不同开发框架下的CSRF拦截实现
  5. 常见问题问答(Q&A)
  6. 进阶防护:现代Web应用的CSRF拦截策略

什么是跨站请求伪造?核心原理解析

跨站请求伪造(Cross-Site Request Forgery,简称CSRF,发音为“sea-surf”)是一种恶意攻击方式,攻击者通过伪造用户的身份,诱导用户在不知情的情况下,向已登录的受信任网站发送非预期的请求,从而执行操作(如转账、改密、发帖等)。

跨站请求伪造如何拦截

核心机制:浏览器自动携带Cookie的特性,当用户登录网站A后,浏览器会存储网站A的会话Cookie,如果用户访问了恶意网站B,B站通过构造一个指向A站的请求(例如图片链接或表单提交),浏览器会自动附带上A站的Cookie,导致A站认为这是用户本人的合法操作。

🔍 举个简单的例子:假设你登录了银行网站,攻击者构造了一个“零元购图片”的链接,你点击后,你的账号可能就向攻击者转账了。


CSRF攻击的典型场景与危害

  • 金融场景:攻击者利用用户已登录的网银会话,发起转账请求。
  • 社交平台:伪造用户发帖、加好友、改密码等操作。
  • 后台管理:如果管理员未防范CSRF,攻击者可修改系统配置或删除数据。

CSRF的核心危害在于:用户无感知地被操纵完成操作,而服务器端无法区分请求是用户主动发出还是恶意伪造。


主流CSRF拦截技术详解

1 同步器令牌模式

原理:服务器生成一个随机且唯一的Token(令牌),存储在会话中,并在每个需要保护的页面(如表单页面)中嵌入该Token,当用户提交请求时,服务器验证请求中的Token与会话中的Token是否一致。

优点:安全性高,是OWASP推荐的首选方案。
缺点:需要在服务端维护Token状态,对无状态API不太友好。

实现示例(Java Spring Security)

// 默认开启CSRF保护,自动生成并验证Token
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

2 同源检测(Origin/Referer验证)

原理:检查HTTP请求头中的Origin或Referer字段,判断请求来源是否与当前站点同源。

适用场景:适用于GET请求或无需Token的简单操作。
风险:Referer可能被浏览器屏蔽(如HTTPS→HTTP跳转),Origin可能为空(如通过书签访问)。

3 双重提交Cookie

原理:服务器在用户首次访问时,在Cookie中设置一个随机值,在请求中要求客户端额外提交该值(例如作为请求参数或自定义头),服务器对比Cookie中的值与请求中提交的值是否一致。

优点:无需服务器存储Token,适合无状态API。
缺点:若攻击者能通过子域名或XSS漏洞窃取Cookie,则防御失效。

4 自定义请求头

原理:强制要求所有敏感请求必须携带自定义请求头(如X-Requested-With: XMLHttpRequest),由于浏览器在跨站请求时无法自动设置自定义头(除非使用XMLHttpRequest且受CORS限制),因此可以过滤掉绝大多数CSRF攻击。

典型应用:配合JSON API使用,前端使用Ajax请求时自动添加该头。


不同开发框架下的CSRF拦截实现

框架/平台 实现方式 备注
Spring Security 默认开启,内置Token生成和验证 推荐使用CookieCsrfTokenRepository
Django csrf_token模板标签 + CsrfViewMiddleware 在模板中嵌入{% csrf_token %}
Laravel @csrf指令 + VerifyCsrfToken中间件 Blade模板中使用@csrf
Express.js csurf中间件(已废弃)或自定义Token方案 可配合csurf或自己实现双提交Cookie
ASP.NET Core Antiforgery服务 + ValidateAntiForgeryToken 通过@Html.AntiForgeryToken()保护表单
Go/gin 使用自定义中间件检查Token或Origin 推荐使用https://github.com/utrack/gin-csrf

常见问题问答(Q&A)

Q1:CSRF和XSS攻击有什么区别?
A:XSS利用的是浏览器对用户输入的不信任,注入恶意脚本;而CSRF利用的是服务器对用户请求的信任,XSS可以绕过CSRF防御,因此最佳实践是同时防御两者。

Q2:Token存储在Cookie中安全吗?
A:不安全,如果攻击者通过XSS或子域名攻击获取了Cookie,那么双重提交Cookie方案便失效,建议将Token存放在服务器会话中,并通过隐藏字段传递给客户端。

Q3:只使用同源检测是否足够?
A:不足,部分浏览器可能不支持Origin头,或者Referer可被伪造,同源检测作为辅助防御措施,应配合Token使用。

Q4:RESTful API如何处理CSRF?
A:对于无状态API(使用JWT Token),CSRF风险较低,因为JWT通常通过Authorization头传递,而非Cookie,但仍建议限制CORS策略,并使用自定义头标识请求来源。

Q5:CSRF防御会对用户体验有负面影响吗?
A:合理设计时基本无影响,Token通常在前端框架中自动注入(如Axios的拦截器),用户无感知,但需要注意Token的过期和刷新策略。


进阶防护:现代Web应用的CSRF拦截策略

在单页应用(SPA)和微服务架构流行的今天,CSRF防御需要更全面的考量:

  1. 使用SameSite Cookie属性:设置SameSite=StrictLax可阻止浏览器在跨站请求中附带Cookie,这是现代浏览器的原生防御能力,推荐所有新项目启用。

  2. 结合CORS策略:严格限制允许的来源域名,避免被第三方站点发起请求。

  3. 多因子验证:对敏感操作(如转账、删除账户)增加二次验证(如短信验证码、生物识别)。

  4. 监控与日志:记录所有敏感操作的请求来源、时间、IP等信息,异常时告警。

  5. 前端配合:在SPA中,使用CSRF Token与前端路由跳转相结合,确保每个API请求都有Token携带。

抱歉,评论功能暂时关闭!