X-Frame-Options
X-Frame-Options 控制页面是否可以被 iframe 嵌入,防御点击劫持攻击。
#type / concept
#status / evergreen
#tech / security
#resource / http
#platform / browser
[!info] related notes
- 所属 MOC: security-moc
- 总览: http-response-headers
- 现代替代: CSP(frame-ancestors 指令)
- 并列安全头: HSTS, x-content-type-options, referrer-policy, permissions-policy
X-Frame-Options
一句话定义
X-Frame-Options 告诉浏览器:这个页面是否允许被其他页面通过 iframe 嵌入,用于防御点击劫持攻击。
它要解决什么问题
点击劫持(Clickjacking):攻击者在自己的页面上用透明 iframe 嵌入目标网站,用户以为在点击攻击者的页面,实际上点击的是目标网站上的按钮(比如”确认转账”)。
攻击者的页面(可见)
└── 透明 iframe 嵌入银行网站(用户看不见)
└── 用户点击"领取奖品",实际点击的是"确认转账"
指令
DENY
X-Frame-Options: DENY
不允许任何页面 iframe 嵌入。包括同源页面也不行。
SAMEORIGIN
X-Frame-Options: SAMEORIGIN
只允许同源页面嵌入。比如 app.example.com 的页面可以被 app.example.com 的其他页面 iframe,但不能被 evil.com 嵌入。
现代替代:CSP frame-ancestors
CSP 的 frame-ancestors 指令比 X-Frame-Options 更灵活:
# X-Frame-Options 只有 DENY 和 SAMEORIGIN 两个选项
X-Frame-Options: SAMEORIGIN
# CSP frame-ancestors 可以指定具体来源
Content-Security-Policy: frame-ancestors 'self' https://partner.example.com
# 完全禁止嵌入
Content-Security-Policy: frame-ancestors 'none'
# 允许特定域名嵌入
Content-Security-Policy: frame-ancestors 'self' https://embed.example.com
对比
| 能力 | X-Frame-Options | CSP frame-ancestors |
|---|---|---|
| 完全禁止 | DENY | frame-ancestors 'none' |
| 只允许同源 | SAMEORIGIN | frame-ancestors 'self' |
| 允许特定域名 | 不支持 | frame-ancestors 'self' https://example.com |
| 多个域名 | 不支持 | 支持 |
| 通配符 | 不支持 | 支持 |
推荐
如果只需要简单防护,X-Frame-Options 足够。如果需要精细控制(比如允许合作伙伴嵌入),用 CSP frame-ancestors。
两者可以同时设置,浏览器会同时检查。
边界与易混淆点
- X-Frame-Options 是响应头,不是请求头:由被嵌入的页面设置,不是由 iframe 所在页面设置。
- 它不影响 JavaScript 的
window.open:只管 iframe/object/embed 等嵌入方式。 ALLOW-FROM已废弃:曾经有ALLOW-FROM uri选项,但因浏览器支持不一致已被废弃,用 CSPframe-ancestors替代。- 同源检测基于页面的 URL,不是 iframe 的 URL:
SAMEORIGIN检查的是被嵌入页面的 origin 和嵌入它的页面的 origin 是否相同。