摘要
X-Frame-Options: SAMEORIGIN允许网页声明:别让其他来源把我装进框架。2013 年 RFC 记录了部分浏览器的盲点:它们只比较受保护页面与最外层页面。- 若 A 页面套入 B 页面,B 再套入 A 的受保护页面,只看两端就会得到“A 等于 A”,中间的 B 却没受检。W3C 2016 年的
frame-ancestors要求浏览器检查每一层祖先。
第三层窗口藏在中间
想象一个来自 A 网站的蓝色页面,里面放着 B 网站的红色框架。B 再试图把 A 的敏感页面嵌在自己的框架里。敏感页面返回 X-Frame-Options: SAMEORIGIN,要求只让同源页面嵌入。浏览器若只拿它与最外层蓝色页面比较,结果是 A 对 A,放行。真正紧贴敏感页面的红色 B 框架留在中间,反而没有被问到。
2013 年 10 月发布的 RFC 7034描述的就是这种机制。它是一份 Informational 文档,记录当时各浏览器对头字段的处理差异。头字段要防的是点击劫持:某个网站可以利用叠放的页面,让用户以为自己点击了眼前的按钮,实际触发另一页面的操作。RFC 里的商店确认页只是防护例子;A/B/A 三层结构说明可行的失误路径,并未给出一家真实商店的事故统计。
网站写了规则,浏览器读错层数
受保护页面的服务器在 HTTP 响应里发送 X-Frame-Options。DENY 禁止所有嵌入,SAMEORIGIN 允许同源嵌入,ALLOW-FROM 指定单一许可来源。网站决定边界,浏览器负责执行。只有两层窗口时,这套分工很直观;出现第三层时,“同源”究竟要与哪一层比较,就成了安全问题。
RFC 指出,不同实现的判断方式并不一致。若浏览器只比较最外层和受保护层,它会跳过一个可能由陌生网站控制的中间层。错误不在于网站没有发出头字段,也不在于 SAMEORIGIN 拼写不对。浏览器没有走完整棵嵌套树。两端颜色相同,不能证明中间的门属于同一个人。
W3C 让浏览器逐层点名
W3C 2016 年 12 月的 Content Security Policy Level 2 推荐标准定义了 frame-ancestors。浏览器准备把受保护资源放进框架前,必须列出所有祖先窗口,并逐一检查对应页面的地址是否符合许可来源。任何一层失败,就停止加载。在 A/B/A 结构中,中间 B 不合格;最上层 A 合格也救不了它。
W3C 明确把这种全链检查与旧 X-Frame-Options: SAMEORIGIN 的顶层比较区分开,并说 frame-ancestors 取代旧头字段;两者同时存在时,应执行 CSP 规则。新指令还能列出多个许可来源,旧 ALLOW-FROM 只能写一个。真正改变安全判断的,是从“看两端”改成“查每一层”。
规则还必须到达浏览器会执行的位置。RFC 说,写在 meta http-equiv 里的 X-Frame-Options 会被忽略。W3C 对 frame-ancestors 也不接受 meta 元素承载。笼统写了 default-src 'none',不会自动禁止别人嵌入页面。网站得把嵌入规则明确放进正确的响应策略。
网站能说出谁可包围自己的内容;只有访客的浏览器看得见当前完整的窗口链。安全承诺要兑现,浏览器就得把这条链查到底。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限战略圈层会员
战略圈层
所有读者均可浏览。加入并登录后可解锁档案简报。
加入战略圈层仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance





