5月27日 21:45
什么是 SameSite Cookie?它如何防御 CSRF 和 XSS 攻击?
答案
SameSite 是 Cookie 的一个属性,控制浏览器是否在跨站请求中携带 Cookie。它是防御 CSRF 攻击的核心手段,也能在一定程度上限制跨站 XSS 的危害扩散。
三种模式的区别:
| 模式 | 跨站请求是否携带 Cookie | 典型场景 |
|---|---|---|
| Strict | 完全不携带 | 银行、支付等高安全应用 |
| Lax | 仅顶层导航(如点击链接)携带,异步请求不携带 | 大多数 Web 应用的推荐默认值 |
| None | 全部携带,必须配合 Secure | 第三方登录、iframe 嵌入等跨站场景 |
javascriptres.cookie('sessionId', token, { httpOnly: true, secure: true, sameSite: 'lax' // 现代浏览器默认值 });
为什么 Lax 是推荐默认值?
Strict 最安全但有体验问题:用户从邮件或搜索引擎点击链接进入网站时,Cookie 不会被发送,导致登录态丢失。Lax 在安全与体验间取了平衡——顶层 GET 导航携带 Cookie 保证正常跳转,POST 和异步请求不携带,阻断 CSRF。
SameSite 能防 XSS 吗?
不能完全防。SameSite 限制的是跨站请求中的 Cookie 发送,但 XSS 发生在同站内,脚本可以直接读取非 HttpOnly 的 Cookie 或发起同站请求。正确做法是 SameSite + HttpOnly + CSP 组合使用:
javascriptres.cookie('sessionId', token, { httpOnly: true, secure: true, sameSite: 'strict' }); // 配合 CSP 限制脚本来源 res.setHeader('Content-Security-Policy', "script-src 'self'");
None 模式有什么坑?
SameSite=None 必须同时设置 Secure,否则浏览器会拒绝。而且 None 模式下 Cookie 在所有跨站请求中都会发送,等于放弃了 SameSite 的防护,必须额外依赖 CSRF Token 等机制兜底。
追问
- Chrome 80+ 未显式设置 SameSite 时默认行为是什么?——默认 Lax,未声明的 Cookie 在跨站 POST/iframe/fetch 中不会发送。
- SameSite=Lax 下,哪些跨站请求会携带 Cookie?——顶层 GET 导航(
<a>点击、window.open),不包含 POST 表单、iframe、fetch/XHR。 - 如果应用需要嵌入第三方 iframe 并保持登录态,怎么处理?——SameSite=None; Secure + CSRF Token 双重防护。