Cookie校验如何抵御CSRF

wen 网络安全 22

本文目录导读:

Cookie校验如何抵御CSRF

  1. 为什么“普通Cookie校验”不能抵御CSRF?
  2. 真正的武器:基于Cookie的CSRF防御方案
  3. 总结对比
  4. 最佳实践建议

Cookie校验本身并不能直接抵御CSRF攻击,甚至在某些情况下会为CSRF攻击提供便利,CSRF攻击的核心正是利用了浏览器自动携带Cookie(尤其是认证Cookie)的特性。

要理解Cookie校验如何参与抵御CSRF,需要先区分两个概念:

  1. 普通的Cookie认证:浏览器自动在跨站请求中携带Cookie。这恰好是CSRF能成功的前提,而不是防御手段。
  2. 专门为防御CSRF设计的Cookie技术(如SameSite Cookie、Double Submit Cookie模式)。这才是“利用Cookie抵御CSRF”的正确含义。

以下是详细解释:

为什么“普通Cookie校验”不能抵御CSRF?

假设银行网站 bank.com 使用Session Cookie认证,用户登录后,浏览器持有这个Cookie。

  • 正常操作:用户访问 bank.com/transfer?to=Alice&amount=100,浏览器自动带上Cookie,银行端校验Cookie通过,转账成功。
  • CSRF攻击:用户访问了攻击者精心构造的页面 evil.com,该页面里有一个隐藏的表单或图片,自动向 bank.com/transfer?to=Hacker&amount=100000 发起请求。
    • 浏览器会自动带上 bank.com 的Cookie。
    • 银行后端只校验了Cookie(“你是谁?”),但没有校验是“谁发起的这个请求”(“你是在我的网站上主动点的按钮,还是被evil.com欺骗的?”)。
    • 校验通过,转账完成。

普通Cookie校验只是在验证“请求是来自已登录的用户”,但无法区分该请求是用户自愿发起的,还是被恶意网站伪造发起的,所以它无法防御CSRF。

真正的武器:基于Cookie的CSRF防御方案

既然问题出在“浏览器会自动带Cookie”,那么防御思路就是设计一套机制,让攻击者无法构造出合法的请求,其中两种主流方案都利用了Cookie的某种特性。

SameSite Cookie(最现代、最推荐的方案)

这是直接在Set-Cookie时添加的属性,告诉浏览器什么时候该带这个Cookie,它能从根本上解决问题。

  • SameSite=Lax (推荐默认)

    • 防御原理:浏览器会阻止跨站请求携带Cookie,但允许一部分“顶级导航”(如用户点击链接进入)携带。
    • 效果evil.com 通过 <form> <img>fetch 发起的POST/GET请求,都不会携带Cookie,后端校验时发现没有或无效的Cookie,拒绝请求。
    • Cookie设置示例Set-Cookie: session_id=abc123; SameSite=Lax
  • SameSite=Strict

    • 防御原理:完全禁止跨站请求携带Cookie,包括用户点击链接。
    • 效果:安全性最高,但用户体验可能受影响(比如从Gmail链接到银行页面,需要重新登录)。

优点:无需后端修改代码,前端零配置,是防御CSRF的最强方案之一。 缺点:依赖浏览器支持(现代浏览器都已支持)。

Double Submit Cookie(双重提交Cookie模式)

当无法使用SameSite(比如需要兼容非常老的浏览器)时,这是一个经典模式。

  • 工作原理

    1. 用户登录后,服务器在Cookie中设置一个随机且保密的Tokencsrf_token=abc123)。
    2. 服务器在返回的表单或页面中,也会把这个Token作为隐藏字段请求头写入。
    3. 当用户提交请求时,浏览器会自动携带该Token(在Cookie中),同时用户手动提交的表单中也包含该Token(在请求体/请求头中)。
    4. 服务器校验:Cookie中的Token 是否等于 请求体/请求头中的Token
  • 为什么能防御CSRF?

    • 攻击者在 evil.com 构造请求,他可以轻易触发浏览器发送带Cookie的请求。
    • 攻击者无法读取 bank.com 的Cookie(受同源策略限制)。
    • 攻击者也无法知道 Cookie里存的是什么值。
    • 攻击者无法在 evil.com 的请求体或者请求头中构造出和Cookie里一模一样的Token,当服务器比较两者,发现不匹配,就会拒绝请求。

优点:纯前端+后端实现,无需服务端存储额外的Token状态(重复校验逻辑)。 缺点:需要前后端协作,每次请求都需要手动携带Token。

总结对比

方法 原理 是否依赖Cookie本身 防CSRF效果
普通Cookie校验 只验证“用户已登录” 是(作为认证凭证) 无效 (甚至帮倒忙)
SameSite Cookie 声明“跨站时别带Cookie” 是(通过修改Cookie属性) 极强(最推荐)
Double Submit Cookie 利用攻击者无法读取Cookie的值 是(作为秘密载体) (经典方案)

最佳实践建议

  1. 首选 SameSite Cookie:为所有主要会话Cookie设置 SameSite=Lax,这能阻挡绝大多数CSRF攻击,且几乎零成本。
  2. 搭配 SameSite 使用安全方案:如果必须支持复杂跨站场景(如支付回调),不要依赖Cookie的自动携带,而是使用:
    • CSRF Token:服务器生成的随机Token,存入Session,前端需要获取后在请求Header中携带(不是Cookie)。
    • Origin/Referer验证:检查请求头中的 OriginReferer 字段,确保请求来自本站。
  3. 避免不安全模式:不要为了兼容性轻易使用 SameSite=None,如果必须用(比如需要第三方Cookie场景),必须同时启用 CSRF Token 或 Origin验证。

一句话结论:Cookie校验本身是CSRF攻击的目标,而不是解药。真正能抵御CSRF的,是SameSite=Cookie属性 或基于秘密Token的校验机制(其中Double Submit Cookie是利用了Cookie无法被跨站读取的特性)

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