限制页面被嵌套
X-Frame-Options 控制页面能否被 iframe 或 frame 嵌入,用于防点击劫持:攻击者把真实站点套在自己的页面里,诱导用户在看不见全貌的情况下点击。DENY 完全禁止嵌套,SAMEORIGIN 只允许同源页面嵌入。现代等价且更细粒度的能力是 CSP 的 frame-ancestors,两者同时存在时以 CSP 为准。
基本信息
| 方向 | 响应头 |
|---|---|
| 规范 | RFC 7034 |
| 取值 | DENY、SAMEORIGIN;ALLOW-FROM 已废弃,各浏览器支持不一致 |
| 现代替代 | Content-Security-Policy: frame-ancestors 支持按来源白名单控制 |
| 适用范围 | 整个页面响应,对 XHR 与静态资源无意义 |
取值对照
| 取值 | 效果 | 适用场景 |
|---|---|---|
| DENY | 任何页面都不能嵌套,包括同源 | 后台管理、支付等敏感页面 |
| SAMEORIGIN | 仅同源页面可嵌套 | 需要在自家页面内嵌自己的子页面 |
| ALLOW-FROM 网址 | 已废弃,现代浏览器忽略 | 不要在新项目中使用 |
| frame-ancestors 列表 | CSP 提供的细粒度白名单 | 需要允许特定合作方嵌入时 |
Nginx 与 CSP 配置
Nginx 与 CSP 配置
# 基础写法
add_header X-Frame-Options SAMEORIGIN always;
# 需要更细粒度时用 CSP(与上面的头同时存在时以 CSP 为准)
add_header Content-Security-Policy "frame-ancestors 'self' https://partner.example.com" always;
# 校验
curl -sI https://example.com/ | grep -i -E 'x-frame-options|content-security-policy'典型使用场景
- 后台管理系统禁止被任何页面嵌套,防点击劫持
- 站内已有 iframe 结构时用 SAMEORIGIN 保留自身嵌入能力
- 开放平台需要允许合作方嵌入时改用 CSP 白名单
- 安全基线检查与等保测评中的必查项
现代等价能力是 CSP 的 frame-ancestors,粒度更细:两者同时返回时以 CSP 为准;新项目建议直接用 CSP,老浏览器兼容才保留 X-Frame-Options。
嵌入自家子域页面时配 DENY 会把自己的界面也挡掉:跨子域在多数浏览器中不算同源,应使用 SAMEORIGIN 或通过 CSP 白名单显式列出各子域。
灰度与多域名场景要逐域核对:主站配了头而临时域名没配,攻击者可以拿未加头的入口做嵌套,安全评审时应把所有解析到同一服务的域名一起检查。