HttpOnly Cookie
HttpOnly Cookie 是只能由浏览器随请求自动携带、但不能被 JavaScript 通过 document.cookie 读取的 Cookie 安全属性,常用于降低 XSS 窃取会话凭证的风险。
#type / concept
#status / growing
#tech / dev / frontend
#platform / browser
#resource / http
[!info] related notes
- 所属 MOC: 前端基础 MOC, HTTP 与前端网络请求
- 前置概念: Cookie、Session、Token
- 并列概念: SameSite, Cookie 和 LocalStorage 的区别
- 安全相关: XSS 跨站脚本攻击, CSRF, DevTools Cookie 调试
HttpOnly Cookie
一句话定义
HttpOnly Cookie 是带有 HttpOnly 属性的 Cookie:浏览器仍会在符合域、路径和站点策略时自动携带它,但页面里的 JavaScript 不能通过 document.cookie 读取它。
它要解决什么问题
普通 Cookie 如果能被页面脚本读取,一旦页面发生 XSS,攻击者就可能直接把会话标识、refresh token 或其他敏感 Cookie 偷走。
HttpOnly 的目的就是降低这种风险:
- 浏览器继续负责自动带 Cookie 发请求
- 但前端脚本不能直接把它读出来
所以它常被用来保存:
- Session ID
- Refresh Token
- 某些服务端会话标识
核心机制 / 工作原理
1. HttpOnly 限制的是“脚本读取”,不是“网络发送”
当服务端用 Set-Cookie 下发:
Set-Cookie: refreshToken=abc123; HttpOnly; Secure; SameSite=Lax; Path=/
浏览器会做两件事:
- 把这条 Cookie 存起来
- 在后续符合条件的请求里自动带上它
但页面脚本不能这样拿到它:
document.cookie
也就是说,HttpOnly 不会阻止浏览器自动发 Cookie,只会阻止 JavaScript 直接读它。
2. HttpOnly 只能由服务端设置
这是一个非常容易弄错的点:
- 前端 JavaScript 不能把某条 Cookie 设置成
HttpOnly - 只能由服务端通过
Set-Cookie响应头下发
所以这类 Cookie 的典型控制方式在后端,不在前端。
3. 它常和 Secure、SameSite 一起使用
真实工程里,HttpOnly 很少单独讨论,通常会和:
Secure:只在 HTTPS 下发送- SameSite:限制跨站自动携带边界
一起搭配。
一个很常见的安全组合是:
HttpOnlySecureSameSite=Lax或SameSite=Strict
最小例子 / 最小场景
一个常见认证设计是:
- access token 放在内存里,前端手动放到
Authorization头 - refresh token 放在
HttpOnly Cookie里,由浏览器自动带给刷新接口
这样做的考虑通常是:
- access token 生命周期短,便于前端控制
- refresh token 更敏感,尽量不暴露给 JavaScript
它能防什么,不能防什么
能降低什么风险
- 降低 XSS 直接读取 Cookie 并外传的风险
- 降低“前端代码随手把敏感凭证打印出来或持久化”的风险
不能解决什么问题
- 不能阻止浏览器自动携带 Cookie 发请求
- 所以它本身不能单独防住 CSRF
- 也不能阻止攻击者在已经发生 XSS 时直接调用站内接口发恶意请求
换句话说,HttpOnly 保护的是“凭证不容易被脚本读走”,不是“页面只要被注入脚本就完全安全”。
最容易混淆的点
HttpOnly不是“更安全的 Cookie 类型”,而是 Cookie 的一个属性。HttpOnly不能由document.cookie设置,只能由服务端Set-Cookie设置。HttpOnly防的是“读 Cookie”,不是“带 Cookie 发请求”,所以它不能替代 SameSite 或 CSRF Token。- DevTools Application 面板通常仍能看到这条 Cookie;“JS 读不到”不等于“浏览器里完全不可见”。