SameSite
SameSite 是 Cookie 的跨站携带策略:浏览器按 schemeful site 判断 same-site / cross-site,并结合 Strict、Lax、None 决定 Cookie 是否随请求发送;它是 CSRF 的纵深防御而不是完整授权机制。
[!info] related notes
- 所属 MOC: 前端基础 MOC
- Site 与 Origin: Same-Origin
- CSRF: CSRF, XSS vs CSRF
- Cookie: Cookie vs LocalStorage, Cookie、Session、Token 与 JWT 的关系
- 调试: DevTools Cookie 调试
SameSite
一句话定义
SameSite 控制的是:
这个 Cookie 在 cross-site 请求中是否允许被浏览器自动携带。
它不是:
- Cookie 是否能被 JavaScript 读取;
- 用户是否已认证;
- 请求是否有业务权限;
- CORS 是否允许脚本读取 response。
这些是不同安全边界。
Site 不是 Origin
SameSite 判断使用的是 site,不是完整 origin。
现代浏览器对 SameSite 采用 schemeful site:
site
≈ scheme + registrable domain
例如:
https://a.example.com
https://b.example.com
通常属于 same-site,因为 scheme 相同、registrable domain 都是 example.com。
但:
http://example.com
https://example.com
在 schemeful same-site 规则下属于 cross-site。
端口参与 origin 判断,但不参与 site 判断。
所以:
same-site 比 same-origin 更宽。
Strict
Set-Cookie: session=...; SameSite=Strict
Strict 只在 same-site 请求中发送该 Cookie。
典型结果:
- 站内导航:可以发送;
- 从外部网站点击链接进入:该 Strict Cookie 不发送;
- cross-site fetch / iframe / form:不发送。
适合:
- 高敏感 Cookie;
- 可以接受跨站进入时暂时没有登录态的场景。
注意:
Strict 约束的是这个 Cookie,不等于“浏览器完全禁止所有第三方 Cookie”。
Lax
Set-Cookie: session=...; SameSite=Lax
Lax 在 same-site 请求中发送,同时允许部分 cross-site top-level navigation + safe method 场景。
常见允许:
外部站点
→ 用户点击链接
→ top-level GET navigation
→ Cookie 可以发送
常见不允许:
- cross-site fetch/XHR;
- iframe 子导航;
- image/script 等子资源;
- 一般 cross-site POST/PUT/DELETE。
这也是为什么 Lax 常作为普通 session Cookie 的合理默认策略。
默认 Lax 的细节
现代浏览器通常把未显式声明 SameSite 的 Cookie 按 Lax 类策略处理。
但某些浏览器的 implicit Lax default 带有更宽松的兼容行为,例如刚设置不久的 Cookie 可能在短时间内随 cross-site POST 发送。
因此生产配置更稳的做法是:
显式设置 SameSite,而不是依赖浏览器默认值。
None
Set-Cookie: widget_session=...; SameSite=None; Secure
None 表示 SameSite 自身不限制 cross-site 携带。
但必须同时:
SameSite=None
+ Secure
也就是说通常只能通过 HTTPS 发送。
典型场景:
- cross-site iframe;
- 第三方嵌入;
- 某些跨站 SSO 流程。
但:
SameSite=None 不等于“Cookie 一定会发送”。
浏览器的 third-party cookie / tracking prevention / storage partitioning 等隐私策略仍可能进一步限制它。
SameSite 与 Secure / HttpOnly
三者解决不同问题:
| 属性 | 主要控制 |
|---|---|
| SameSite | cross-site 请求是否自动携带 |
| Secure | 是否只通过安全传输发送 |
| HttpOnly | 页面 JavaScript 是否能读取 |
常见 session Cookie:
Set-Cookie: session=...; Path=/; Secure; HttpOnly; SameSite=Lax
并不意味着这套配置适合所有认证架构,但它说明三个属性可以共同工作。
SameSite 与 CSRF
CSRF 的典型条件是:
attacker site
→ 诱导浏览器向 victim site 发请求
→ browser 自动附带 credential
→ server 接受该 unsafe action
SameSite 可以阻断其中很多 cross-site Cookie 自动携带路径。
但它只是 defense in depth。
高风险 unsafe request 仍应考虑:
- CSRF Token;
- Origin / Referer validation;
- Fetch Metadata;
- 正确的 HTTP method;
- re-auth / confirmation;
- authorization。
SameSite 与 CORS
不要混淆:
SameSite
→ Cookie 是否随 cross-site request 自动携带
CORS
→ cross-origin JavaScript 是否能读取 response
一个请求即使被 CORS 阻止读取,也可能已经到达服务器并产生副作用。
所以 CORS 不能替代 CSRF 防御。
SameSite 调试
出现“Cookie 明明存在但请求没带”时,按:
Set-Cookie
→ Browser 是否接受
→ 当前 request 的 site relation
→ SameSite
→ Secure
→ Domain / Path
→ credentials
→ third-party cookie policy
逐层检查。
学习检查
- Site 与 Origin 的核心差异是什么?
- 为什么
https://a.example.com与https://b.example.com可以 cross-origin 但 same-site? - 为什么
http://example.com与https://example.com会影响 SameSite 判断? - Strict 与 Lax 对“从外部网站点击链接进入”有什么差异?
- 为什么 SameSite=None 还必须配 Secure?
- 为什么 SameSite=None 仍不能保证第三方 Cookie 一定可用?
- SameSite、HttpOnly、Secure 分别防哪一层问题?
- 为什么 CORS 不能替代 CSRF 防御?