在初步接触CSRF(跨站请求伪造)时,很多人会产生类似的疑问:如今的关键操作(如转账、删除账户)大多需要二次确认,怎么可能仅靠一个链接就完成攻击?
这种质疑非常敏锐,实际上正好点中了CSRF攻防演变的核心。
一、为什么CSRF“看起来很难生效”?
过去,CSRF曾被称为“沉睡的巨人”,因为早期许多Web应用确实缺乏对关键操作的防护,攻击者只需构造一个隐藏表单或图片链接,诱使用户在已登录状态下点击,就能在用户无感时完成转账或删号。
但随着安全意识的提升,以下三道防线已经普及,使得传统CSRF攻击难以奏效:
-
二次确认的强制化
现代Web应用对资金流转、权限变更等敏感操作,普遍强制要求图形验证码、原密码或短信/邮箱验证码。这些信息攻击者无法伪造,相当于为关键操作加了一把无法绕过的锁。 -
SameSite Cookie的普及
现代浏览器(Chrome/Edge等)默认将Cookie的SameSite属性设为Lax,这直接阻断了大批CSRF攻击。第三方发起的请求在跨站时,浏览器默认不会携带用户的身份凭证Cookie,攻击者连用户的登录态都无法利用。 -
框架内置防御
现代开发框架(如Spring Security、Django等)默认开启CSRF Token校验。服务端生成的随机Token必须随表单提交,攻击者无法从第三方页面获取这个Token,自然无法构造有效请求。
二、SameSite=Lax 是什么?
SameSite是浏览器为Cookie设置的一道“门禁规则”,Lax(宽松模式)是其属性值之一,它的行为规则如下:
- 不允许:当请求是跨站且由第三方触发时(如恶意网站中的隐藏表单或脚本发起的请求),浏览器默认不带Cookie。这直接防御了CSRF中最经典的“隐藏表单”攻击场景。
- 允许:当跨站请求是由顶级导航触发的,比如用户主动点击链接从A网站跳转到B网站时,浏览器会允许携带Cookie。这保证了用户的正常浏览体验(如从博客点击链接进入购物车)不受影响。
相比更严格的Strict模式(完全禁止任何跨站携带),Lax在安全性与用户体验之间取得了平衡。自从Chrome 80开始,它被设为大多数Cookie的默认值,这也解释了为什么如今单纯诱骗点击很难再利用用户的登录态。
三、恶意链接 vs 隐藏表单:两种攻击变体
这两种攻击方式的区别主要在于利用的HTTP方法不同,但本质都是伪造请求,让用户在已登录状态下不知不觉执行了攻击者指定的操作。
| 攻击方式 | 利用方法 | 适用场景 |
|---|---|---|
| 恶意链接 | 构造带参数的URL(如http://bank.com/transfer?to=attacker&amount=1000),通过<img>标签或诱导点击自动加载 | 针对 GET 请求 的敏感操作 |
| 隐藏表单 | 在恶意网页中嵌入隐藏的<form method="POST">,通过JavaScript自动提交 | 针对 POST 请求 的敏感操作 |
两者在攻击逻辑上完全一致——都是跨站利用用户已有的身份凭证,选择哪种方式仅取决于目标接口接受的请求方法。
但在SameSite=Lax的默认规则下,两者的境遇不同:
- 对于GET链接:用户主动点击时,浏览器仍会携带Cookie。因此,如果敏感操作被设计为GET,依然存在风险,这也是现代应用几乎不再用GET处理敏感操作的原因之一。
- 对于POST表单:跨站提交的请求不会自动携带Cookie(除非表单提交触发了顶级导航),这使得传统的POST型CSRF攻击在默认配置下基本失效。
四、结论:CSRF并未消失,而是转移了
基于日常使用体验得出的“二次确认是防御关键”的直觉,完全正确。正是二次确认、SameSite默认策略、CSRF Token等机制的组合,让早期那种“一个链接删号”的攻击在面向公众的高价值服务中几乎绝迹。
然而,CSRF的威胁并未完全消失,而是转移到了非敏感但高价值的操作上。例如:
- 修改收货地址导致财物被盗
- 绑定攻击者邮箱实现长期权限维持
- 在社交平台强制关注或转发
这些操作往往不需要二次确认,却能构成严重业务损失。
总结来说,如果发现某个敏感操作“只需要一个链接就能执行”,那它大概率就是CSRF的潜在风险点。