cookie的SameSite属性

SameSite 是 Cookie 的一种属性,主要用于防止跨站请求伪伪造(CSRF,Cross-Site Request Forgery)攻击。它通过控制第三方 Cookie 的发送时机,来保护用户的隐私和安全。

在深入 SameSite 之前,我们需要明确两个概念:

  • 第一方 Cookie (First-party Cookie): 你当前访问的网站(地址栏里的域名)写入的 Cookie。
  • 第三方 Cookie (Third-party Cookie): 页面中嵌入的其他网站(如广告、图片、iframe 插件)写入的 Cookie。

1. 核心概念:什么是"同站 (Same-Site)"?

SameSite 的"站(Site)"和我们平时说的"同源策略 (Same-Origin)"不同,它的定义更宽松。

满足以下条件的两个 URL 被认为是同站(Same-Site)的:

有效顶级域名 + 一级域名(eTLD+1) 相同

  • TLD 是指 .com.org 等。
  • eTLD(有效顶级域名)是指像 .com.cn.co.uk 这种复合域名。
  • 举个例子:
    • www.baidu.comtieba.baidu.com 属于同站 (因为都是 baidu.com)。
    • baidu.comgoogle.com 属于跨站(Cross-Site)
    • a.github.iob.github.io 属于跨站 (因为 github.io 是一个 eTLD,它的下一级才是一级域名)。

2. SameSite 的三种策略值

SameSite 属性可以设置三个值:StrictLaxNone

① SameSite=Strict (严格模式)

这是最安全的模式。

  • 规则: 任何跨站的请求(无论通过什么方式触发)都绝不发送该 Cookie。只有当你在当前域名下操作,或者地址栏域名完全一致时才会携带。
  • 场景: 比如你在百度(baidu.com)页面里点击了一个指向淘宝(taobao.com)的链接。即使你之前在淘宝登录过,由于是跨站跳转,浏览器在请求淘宝时不会 带上淘宝的 Strict Cookie。
  • 优缺点: 防御 CSRF 效果最好,但极度影响用户体验(比如从邮件里点开一个知乎链接,进去了却发现需要重新登录)。

② SameSite=Lax (宽松模式)

这是目前主流浏览器的默认模式(平衡了安全与体验)。

  • 规则: 拒绝大部分跨站 Cookie 的发送,但允许"导航到目标网址的常规安全跳转"携带 Cookie。
  • 具体而言,只有满足以下两个条件时,跨站请求才会带上 Lax Cookie:
    1. HTTP 方法必须是安全的(通常是 GETPOSTPUTDELETE 等绝对不带。
    2. 必须是顶级导航(Top-level navigation),即该请求会导致浏览器地址栏的 URL 发生变化。
  • 允许带 Lax Cookie 的场景:
    • <a href="..."> 链接跳转。
    • <link rel="prerender" href="..."> 预加载。
    • window.location.replace("...") 或表格的 GET 提交。
  • 禁止带 Lax Cookie 的场景:
    • ajax / fetch 请求。
    • <img src="..."><iframe src="..."><script src="..."> 等隐式加载的资源。
    • POST 表单提交。

③ SameSite=None (无限制)

关闭 SameSite 限制。

  • 规则: 无论同站还是跨站,任何请求都会带上 Cookie(回到了当年的传统行为)。
  • 硬性前提条件: 现代浏览器(Chromium 80 及以上)规定,如果设置了 SameSite=None,就必须同时设置 Secure 属性 。这意味着该 Cookie 只能通过 HTTPS 协议传输,否则浏览器会直接拒绝写入该 Cookie。
  • 场景: 专门用于第三方广告追踪、跨域共享状态、内嵌的第三方 iframe 支付插件等。

3. 三种策略的对比表格

请求类型 示例代码 Strict Lax (默认) None (+Secure)
链接跳转 (GET) <a href="https://site.com"> ❌ 不发送 ✅ 发送 ✅ 发送
预加载 (GET) <link rel="prerender" href="..."> ❌ 不发送 ✅ 发送 ✅ 发送
表单提交 (GET) <form method="GET" action="..."> ❌ 不发送 ✅ 发送 ✅ 发送
表单提交 (POST) <form method="POST" action="..."> ❌ 不发送 ❌ 不发送 ✅ 发送
图片/脚本加载 <img src="...">, <script src="..."> ❌ 不发送 ❌ 不发送 ✅ 发送
框架嵌套 <iframe src="..."> ❌ 不发送 ❌ 不发送 ✅ 发送
异步请求 fetch("..."), axios.get("...") ❌ 不发送 ❌ 不发送 ✅ 发送

4. 如何在服务器端设置?

在 HTTP 响应头(Response Headers)中,通过 Set-Cookie 来指定:

HTTP

复制代码
# 严格模式
Set-Cookie: sid=abc123; SameSite=Strict; Secure

# 默认的宽松模式
Set-Cookie: sid=abc123; SameSite=Lax

# 允许第三方使用(必须带 Secure)
Set-Cookie: sid=abc123; SameSite=None; Secure

5. 总结与开发建议

  1. 敏感操作防范: 涉及修改用户数据、资金安全、核心业务的 Cookie,尽量设为 Strict
  2. 常规会话(Session ID): 保持默认的 Lax 即可,既能防御绝大多数 POST/AJAX 形式的 CSRF 攻击,又不会破坏正常的链接跳转体验。
  3. 跨域共享: 如果你的系统是分布式架构,且使用了不同的一级域名(比如微服务 A 域名是 aaa.com,B 域名是 bbb.com),且需要跨域携带 Cookie,必须使用 SameSite=None; Secure,并确保全站走 HTTPS。
相关推荐
闪闪发亮的小星星3 天前
高斯光以及高斯光公式解释
笔记
cqbzcsq3 天前
CellFlow虚拟细胞论文阅读
论文阅读·人工智能·笔记·学习·生物信息
阿米亚波3 天前
【Windows】QEMU 启动 openEuler aarch64/arm64 架构系统 + 离线软件源
linux·windows·经验分享·笔记·架构·arm
自传.3 天前
尚硅谷 Vibe Coding|第三章(1) Claude Code深度使用与进阶技巧 学习笔记
笔记·学习·尚硅谷·vibecoding
.千余3 天前
【C++】模板进阶全解:非类型参数|全特化|偏特化|分离编译完全指南
开发语言·c++·笔记·学习·其他
自传.3 天前
尚硅谷 Vibe Coding|第二章 AI编程工具生态 学习笔记
笔记·学习·ai编程·尚硅谷·vibe coding
秋波。未央3 天前
Java Agent 开发 · Day 1 学习笔记(含作业完整标准答案)
java·笔记·学习
中屹指纹浏览器3 天前
2026指纹浏览器字体指纹、字体渲染偏差检测与全维度虚拟字体池搭建方案
经验分享·笔记
影寂ldy3 天前
WinForm PictureBox控件 + ImageList组件 完整笔记
开发语言·笔记·swift