Caloogy 文章
English

Cookie 的四道锁:__Host-、Secure、HttpOnly、SameSite

日期
2026 年 8 月 13 日
系列
Web 安全
阅读
3 分钟
主题
WebCookieSessionCsrf

一句话版本

网站记住"你已登录",靠的是浏览器里的一个会话 cookie。拿到它就等于拿到你的账号。 四个属性各堵一条路:Secure 防明文传输被窃听,HttpOnly 防页面脚本(XSS)读取,SameSite 防别的网站冒用(CSRF),__Host- 前缀防同域名下的其他子站覆盖。再加上"高权限会话要短",就是会话安全的基本功。

全文分三层:

  1. 通俗理解:cookie 是一张自动出示的通行证
  2. 实际用处:会话劫持和 CSRF 的真实后果
  3. 原理与工程要点:每个属性的规则、SSO 会话和高权限会话分离

第一层:通俗理解

1.1 自动出示的通行证

你登录一次后,网站发给浏览器一张"通行证"(cookie)。之后每次访问这个网站,浏览器都会自动把它带上,网站一看就知道是你。

"自动"带来方便,也带来三个问题:

问题 比喻
通行证在路上被人看到 在公共 Wi-Fi 上明文传输
屋里混进了小偷,把通行证复印了 网页被注入恶意脚本(XSS),脚本读走 cookie
别人骗你去敲一扇门,你的通行证被自动出示了 恶意网站让你的浏览器向银行发请求(CSRF)

第二层:实际用处

Caloogy Wallet 也采用了严格的 cookie 属性。


第三层:原理与工程要点

3.1 一个"满配"的会话 cookie

Set-Cookie: __Host-session=随机长字符串; Secure; HttpOnly; SameSite=Strict; Path=/; Max-Age=...
属性 规则 防什么
Secure 只在 HTTPS 连接中发送 网络窃听
HttpOnly 页面 JavaScript 读不到(document.cookie 里看不见) XSS 直接偷走会话
SameSite=Strict 只有从本站发起的请求才带上 CSRF:别的网站触发的请求不带 cookie
SameSite=Lax 跨站的普通链接跳转会带,跨站的表单 POST、图片、iframe 不带 大多数 CSRF,又不影响从外部链接点进来时保持登录
__Host- 前缀 浏览器强制要求:必须 Secure、Path=/、不能设置 Domain 同一主域下其他子站写入同名 cookie,覆盖你的会话(cookie 注入 / 会话固定)

3.2 HttpOnly 不是万能的

HttpOnly 让脚本"偷不走"cookie,但 XSS 脚本仍然可以在你的页面里、用你的身份直接发请求。所以它只是减小损失,真正防 XSS 要靠输入输出编码和 CSP(见《CSP与SRI》)。

3.3 SameSite 之外,再验一次 Origin

SameSite 依赖浏览器实现,老浏览器或某些特殊跳转可能不按预期工作。服务端对所有会修改状态的请求再检查一次 Origin 头(或使用 CSRF token),形成双保险。

3.4 会话分级

会话 时长 能做什么
普通登录(SSO) 可以长,以周计 浏览、只读
高权限会话 短:空闲很快过期,并有绝对上限 动钱、改安全设置

两者分开签发:高权限会话在普通会话之上额外要求一次强认证(如 passkey)。普通会话被吊销时,高权限会话也必须同时失效。

3.5 "same-site" 不等于 "same-origin"

a.example.com 和 b.example.com 是同站(same-site)但不同源(cross-origin)。SameSite 挡不住同一主域下兄弟子站发起的请求,这正是高价值应用要单独隔离、并用 __Host- 前缀的原因(见《同源策略与子域名隔离》)。


总结

属性 一句话
Secure 只走 HTTPS
HttpOnly 脚本读不到
SameSite 别的网站用不了
__Host- 兄弟子站改不了
会话分级 动钱的会话要短、要额外认证