0

0

CSRF攻击怎样防御?Token验证教程

雪夜

雪夜

发布时间:2025-07-09 09:19:01

|

786人浏览过

|

来源于php中文网

原创

防御csrf攻击的核心方法是采用同步令牌模式,具体步骤如下:1.服务器生成唯一且不可预测的csrf令牌并与用户会话绑定;2.将令牌嵌入html表单隐藏字段或ajax请求头;3.用户提交请求时携带该令牌;4.服务器验证令牌与会话中存储的是否一致,不匹配则拒绝请求。此外,辅助手段包括samesite cookie、referer校验、自定义请求头、double submit cookie等。实现时需注意令牌生命周期、存储安全、放置位置、错误处理及利用框架内置支持等最佳实践。

CSRF攻击怎样防御?Token验证教程

防御CSRF(跨站请求伪造)攻击,最核心且广泛推荐的方法是采用同步令牌(Synchronizer Token)模式。这基本上意味着,每次需要用户执行敏感操作时,我们都要确保请求中包含一个只有我们自己网站能生成并验证的“秘密”令牌,而这个令牌是攻击者无法轻易获取的。

CSRF攻击怎样防御?Token验证教程

解决方案

谈到CSRF防御,尤其是通过令牌验证,它的思路其实挺直观的:确保每一个关键的、可能改变服务器状态的请求,都是从我们自己合法的应用发出的,而不是被某个恶意网站伪造的。

CSRF攻击怎样防御?Token验证教程

具体来说,同步令牌模式是这么运作的:

  1. 令牌生成: 当用户访问一个包含表单(比如修改密码、转账)的页面时,服务器会生成一个独一无二、难以预测的随机字符串,这就是我们的CSRF令牌。这个令牌通常会和用户的当前会话绑定,存储在服务器端的会话中。
  2. 令牌嵌入: 生成的令牌会被巧妙地嵌入到HTML表单中,通常作为一个隐藏字段()。如果是AJAX请求,它可能会被放在一个自定义的HTTP头部里。关键在于,这个令牌绝对不能仅仅放在Cookie里,否则就失去了意义。
  3. 令牌提交: 用户提交表单时,这个隐藏的令牌会随着其他表单数据一起发送到服务器。
  4. 令牌验证: 服务器接收到请求后,会从请求中提取出这个令牌,然后和之前存储在用户会话中的令牌进行比对。如果两者完全匹配,那就说明请求是合法的;如果不匹配,或者令牌干脆就不存在,那么这个请求就会被服务器无情地拒绝,因为它很可能是一个CSRF攻击。

这个机制之所以有效,是因为浏览器的“同源策略”限制了攻击者。一个恶意网站(比如attacker.com)无法读取到我们合法网站(比如bank.com)页面中的内容,包括那个隐藏的CSRF令牌。所以,即使攻击者诱骗用户点击了某个链接,或者自动提交了某个表单,他们也无法在伪造的请求中附带上正确的令牌。没有正确的令牌,服务器自然就不会处理那个请求。

CoCo
CoCo

智谱AI推出的首个有记忆的企业自主Agent智能体

下载
CSRF攻击怎样防御?Token验证教程

为什么仅依赖Cookie验证不足以防御CSRF?

这可能是个初学者常有的疑问,毕竟我们登录后,会话信息不都在Cookie里吗?问题就在于,浏览器在处理跨站请求时,有一个“善意”的默认行为:它会自动附带上目标域名下所有相关的Cookie。这意味着,如果用户已经登录了bank.com,并且bank.com的会话ID存在于用户的Cookie中,那么当用户不小心访问了attacker.com上一个指向bank.com的恶意链接时,浏览器会毫不犹豫地把bank.com的会话Cookie也一并发送过去。

对于bank.com的服务器来说,它看到一个带有有效会话Cookie的请求,自然就会认为这是用户“Alice”发出的合法请求,然后照常处理。它并不知道这个请求实际上是attacker.com伪造的,因为它只认Cookie,而Cookie是浏览器自动带上的。CSRF攻击正是利用了这一点。而CSRF令牌则提供了一个额外的、攻击者无法轻易获取的秘密信息,只有我们自己的前端页面才能知道这个令牌,并把它包含在请求中。这就像是除了身份证(Cookie)之外,还需要一个只有我们内部才知道的“暗号”(Token)才能进入。

除了Token验证,还有哪些辅助防御手段?

虽然令牌验证是防范CSRF的主力军,但安全总是一个多层次的问题。除了令牌,我们还有一些辅助手段,它们能在不同层面提供额外的保护:

  • SameSite Cookies: 这是浏览器层面的一个相对较新的特性,而且效果非常好。通过在设置Cookie时加上SameSite属性(比如SameSite=LaxSameSite=Strict),我们可以指示浏览器在某些跨站请求中不要发送这些Cookie。
    • Strict模式最严格,几乎不发送任何跨站请求的Cookie,安全性最高,但可能影响一些正常的跨站跳转(比如从第三方支付页面跳回)。
    • Lax模式则更为宽松,它允许在顶级导航(比如用户点击链接跳转)时发送Cookie,但在其他类型的跨站请求(如POST表单提交CSRF攻击怎样防御?Token验证教程标签加载)时不发送。对于大多数应用来说,Lax模式提供了很好的平衡,并且已经能有效防御大部分CSRF攻击。
    • 它的优点在于,是浏览器自动执行的,减轻了服务器端的负担。但缺点是,它依赖于浏览器支持,老旧的浏览器可能不生效,并且它也不能覆盖所有复杂的跨站场景。
  • Referer Header 校验: 服务器可以检查HTTP请求头中的Referer字段,这个字段通常包含了请求的来源页面URL。如果Referer指向的不是我们自己的域名,那么就可以拒绝这个请求。
    • 这方法实现起来简单,但可靠性不如令牌。用户或某些代理、浏览器插件可能会出于隐私考虑剥离或篡改Referer头,导致误报。所以,它更像是一个辅助性的“尽力而为”的检查。
  • 自定义请求头: 对于AJAX请求,我们可以要求前端在发送请求时,带上一个自定义的HTTP头(比如X-Requested-With: XMLHttpRequest)。由于同源策略的限制,攻击者的恶意脚本通常无法在跨站请求中添加自定义HTTP头。
    • 这个方法对AJAX请求很有效,但显然,它不适用于传统的HTML表单提交。
  • Double Submit Cookie 模式: 这是令牌模式的一个变体。在这种模式下,CSRF令牌既放在一个Cookie里,也放在一个隐藏的表单字段里。服务器不需要在会话中存储令牌,它只需要验证请求中的Cookie令牌和表单字段令牌是否匹配即可。攻击者依然无法读取到Cookie中的令牌,所以也无法伪造。
    • 它的优点是服务器端可以无状态(不需要为每个用户会话存储令牌),但仍然依赖于同源策略。

在实际项目中实现Token验证有哪些常见坑点和最佳实践?

实际落地CSRF令牌验证,有一些细节需要注意,否则可能事倍功半,甚至引入新的问题:

  • 令牌的生命周期和更新: 令牌不应该永远有效。它应该有一个合理的过期时间,通常与用户会话的生命周期同步。当用户会话刷新或执行敏感操作后,令牌也应该随之更新,以防万一令牌泄露后被重放。但更新频率也不能太高,否则可能影响用户体验,比如用户在表单停留时间过长导致令牌失效。
  • 服务器端令牌存储: 最常见的做法是将令牌存储在用户服务器端的会话中。因此,确保你的会话管理本身是安全的至关重要。如果会话本身被劫持,那么CSRF令牌的防御也就形同虚设了。对于无状态的API,你可能需要考虑将令牌的哈希值存储在数据库中,或者使用JWT(但JWT本身也需要考虑CSRF问题)。
  • 令牌的放置位置: 对于传统的HTML表单,隐藏的input字段是标准做法。对于单页应用(SPA)或大量AJAX请求的应用,将令牌放在自定义的HTTP头部(例如X-CSRF-TokenX-XSRF-TOKEN)是更常见的做法。现代前端框架通常有内置机制来处理这些。
  • 一次性令牌 vs. 会话令牌: 对于大多数CSRF防御场景,一个会话内使用同一个令牌就足够了。但对于极度敏感的操作(如重置密码),你可能会考虑使用一次性令牌,即每个请求都使用一个新令牌,用完即失效。但这会增加复杂性,并可能在网络不稳定导致请求重试时影响用户体验。通常,一个会话令牌已经提供了足够的保护。
  • 令牌不匹配的处理: 当服务器检测到令牌不匹配时,不要只是返回一个笼统的错误。应该记录下这个潜在的攻击尝试,并且可以考虑立即使当前会话失效,然后将用户重定向到登录页面或一个通用的错误页面。切记,不要在错误信息中泄露任何关于令牌失败的具体细节。
  • 利用框架的内置支持: 几乎所有主流的Web开发框架(如Django、Rails、Spring Security、Laravel、Express配合相关中间件)都提供了强大且经过验证的CSRF保护机制,它们通常都实现了同步令牌模式。强烈建议你优先使用这些框架提供的功能,而不是自己从头实现。框架会帮你处理令牌的生成、存储、验证等复杂细节,很多时候甚至是透明的。
  • 全站HTTPS: 虽然HTTPS本身不是直接的CSRF防御,但它是所有Web安全的基础。它能防止中间人攻击,确保通信内容的完整性和机密性,从而避免攻击者在传输过程中篡改令牌或劫持会话Cookie。
  • 持续测试: 安全是一个持续的过程。定期对你的CSRF防御机制进行测试,无论是通过安全扫描工具、渗透测试,还是手动模拟攻击场景,确保你的实现能够经受住考验。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

319

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

277

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

370

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

371

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

81

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

64

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

67

2025.08.05

spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

106

2025.08.06

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Laravel---API接口
Laravel---API接口

共7课时 | 0.6万人学习

PHP自制框架
PHP自制框架

共8课时 | 0.6万人学习

PHP面向对象基础课程(更新中)
PHP面向对象基础课程(更新中)

共12课时 | 0.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号