如何阻止同站点Cookie在跨源请求中被发送?
一、阻止同站点iframe请求发送B的身份验证Cookie的方法
因为A和B属于同站点(共享eTLD+1),SameSite=Strict规则不会阻止Cookie在这种iframe上下文里发送,你可以试试这些方案:
给Cookie加
Partitioned属性:
给B的身份验证Cookie添加上Partitioned,同时保留Secure、HttpOnly和SameSite=Strict。这个属性会让Cookie按顶层站点(也就是A)隔离,A的iframe里发起的请求不会带这个Cookie,但用户直接访问B的时候正常用。示例配置:Set-Cookie: auth=your-token; Domain=b.example.com; Secure; HttpOnly; SameSite=Strict; Partitioned目前Chrome、Edge这些主流浏览器都支持这个属性,直接加就行,不用额外配置。
服务器端判断请求来源,拒绝使用Cookie:
如果没法用Partitioned,可以在B的服务器上检查两个请求头:Sec-Fetch-Site和Sec-Fetch-Dest。如果Sec-Fetch-Site是same-site(说明来自同站点),且Sec-Fetch-Dest是iframe(说明是iframe嵌入的请求),服务器就不要用这个Cookie做身份验证。这种方法不能阻止浏览器发Cookie,但能达到“不认这个Cookie”的效果,和阻止发送的目的差不多。调整Cookie的Domain属性(仅辅助用):
如果之前Cookie设了Domain=example.com(允许所有子域共享),可以改成不指定Domain,默认只绑定b.example.com。但这个方法没法阻止iframe请求发Cookie,只是能不让其他无关子域共用这个Cookie,算是辅助优化。
二、内网站点被攻陷后的点击劫持防护
你说的情况确实存在:要是攻击者拿下了example内网里的任意站点(比如c.example.com),只要目标站点没配置限制该站点的CSP frame-ancestors规则,攻击者就能把目标站点嵌进iframe搞点击劫持。可以这么强化防护:
严格配置CSP的
frame-ancestors规则:
遵循最小权限原则,别随便开宽权限:- 如果站点不需要被任何iframe嵌入,直接设:
Content-Security-Policy: frame-ancestors 'self'; - 如果必须被特定站点嵌入,就明确列出来允许的域名,别用
*.example.com这种通配符——不然被攻陷的内网站点也会被允许。
- 如果站点不需要被任何iframe嵌入,直接设:
加
X-Frame-Options头做兼容:
虽然CSP的frame-ancestors优先级更高,但为了兼容旧浏览器,可以同时设置这个头:- 完全禁止嵌入:
X-Frame-Options: DENY - 只允许自己嵌入:
X-Frame-Options: SAMEORIGIN
要是需要允许特定站点,设X-Frame-Options: ALLOW-FROM https://a.example.com;(不过部分现代浏览器已经弃用ALLOW-FROM了,优先用CSP)。
- 完全禁止嵌入:
内网站点做身份隔离:
给内网站点加严格的访问控制,比如用内网专属的身份验证系统,限制每个站点的权限范围,就算某个站点被攻陷,攻击者也拿不到其他站点的敏感权限。
内容的提问来源于stack exchange,提问作者HH321

