Skip to content

iframe 安全

iframe(内嵌框架)允许在一个页面中嵌入另一个页面,但也引入了多种安全风险:点击劫持、跨域信息泄露和恶意代码注入。本节将介绍 iframe 的 sandbox 属性、allow 属性、CSP frame-ancestors 指令和 X-Frame-Options 响应头的安全配置方法。

前置知识

阅读本节前,建议先了解:CSP 内容安全策略

iframe 安全风险

风险说明
点击劫持透明 iframe 覆盖在正常内容上,诱导用户点击
跨域信息泄露iframe 中的页面可能通过 window.parent 访问父页面信息
恶意代码iframe 中的第三方页面可能包含恶意脚本
资源消耗恶意 iframe 可能消耗带宽和 CPU

sandbox 属性

sandbox 属性为 iframe 施加安全限制:

html
<!-- 完全沙箱(最严格) -->
<iframe src="https://example.com/embed" sandbox></iframe>

<!-- 允许特定功能 -->
<iframe
  src="https://example.com/embed"
  sandbox="allow-scripts allow-same-origin allow-forms"
></iframe>

sandbox 值

允许的操作
(空)最严格,禁止所有功能
allow-scripts允许执行 JavaScript
allow-same-origin允许同源访问(谨慎使用)
allow-forms允许提交表单
allow-popups允许打开新窗口
allow-popups-to-escape-sandbox允许弹出的窗口脱离沙箱
allow-modals允许模态对话框(alert、confirm)
allow-top-navigation允许导航到顶层窗口
allow-downloads允许下载文件
allow-presentation允许嵌入演示

allow-scripts + allow-same-origin 的风险

同时使用 allow-scriptsallow-same-origin 可能允许 iframe 中的脚本移除自身沙箱限制。仅在你完全信任 iframe 内容时使用。

allow 属性

allow 属性为 iframe 配置权限策略(Permissions Policy):

html
<!-- 使用 allow 属性配置特定权限 -->
<iframe
  src="https://example.com/embed"
  allow="camera; microphone; fullscreen"
  allowfullscreen
></iframe>

常用 allow 值

权限说明
camera使用摄像头
microphone使用麦克风
geolocation获取地理位置
fullscreen全屏显示
autoplay自动播放音视频
encrypted-media加密媒体
picture-in-picture画中画模式
clipboard-write写入剪贴板
gyroscope使用陀螺仪
accelerometer使用加速度计

CSP frame-ancestors

frame-ancestors 指令控制哪些页面可以嵌入当前页面:

# 禁止任何页面嵌入
Content-Security-Policy: frame-ancestors 'none';

# 仅允许同源页面嵌入
Content-Security-Policy: frame-ancestors 'self';

# 允许特定域名嵌入
Content-Security-Policy: frame-ancestors 'self' https://partner.example.com;

X-Frame-Options

X-Frame-Options 是 CSP frame-ancestors 的旧版替代,但仍被广泛支持:

# 禁止任何页面嵌入(推荐)
X-Frame-Options: DENY

# 仅允许同源页面嵌入
X-Frame-Options: SAMEORIGIN

# 允许指定域名嵌入
X-Frame-Options: ALLOW-FROM https://partner.example.com

CSP frame-ancestors vs X-Frame-Options

特性X-Frame-OptionsCSP frame-ancestors
支持所有浏览器现代浏览器
多域名不支持(ALLOW-FROM 非标准)支持
规范过时推荐使用
并用可以同时使用优先级更高

点击劫持防护

html
<!-- 方法 1:X-Frame-Options(服务器响应头) -->
<!-- X-Frame-Options: DENY -->

<!-- 方法 2:CSP frame-ancestors -->
<meta http-equiv="Content-Security-Policy" content="frame-ancestors 'none';">

<!-- 方法 3:JavaScript 防护(辅助手段) -->
<script>
  if (window.top !== window.self) {
    window.top.location = window.self.location;
  }
</script>

<!-- 方法 4:CSS 防护(辅助手段) -->
<style>
  /* 防止页面被透明 iframe 覆盖 */
  body {
    display: none !important;
  }
</style>
<noscript>
  <style>body { display: block !important; }</style>
</noscript>

实战示例

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>iframe 安全示例</title>
  <!-- 禁止页面被 iframe 嵌入 -->
  <meta http-equiv="Content-Security-Policy" content="frame-ancestors 'none'">
</head>
<body>
  <h1>安全嵌入第三方内容</h1>

  <!-- 安全的 iframe 配置 -->
  <iframe
    src="https://trusted-partner.com/widget"
    sandbox="allow-scripts allow-forms allow-popups"
    allow="fullscreen"
    allowfullscreen
    width="600"
    height="400"
    loading="lazy"
    title="第三方内容"
    referrerpolicy="no-referrer-when-downgrade"
  ></iframe>

  <!-- 视频嵌入 -->
  <iframe
    src="https://www.youtube.com/embed/dQw4w9WgXcQ"
    sandbox="allow-scripts allow-same-origin allow-popups allow-forms"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
    allowfullscreen
    loading="lazy"
    title="YouTube 视频嵌入"
  ></iframe>
</body>
</html>

注意事项

  1. 始终使用 sandbox:即使是可信的内容也应限制权限
  2. 不要同时使用 allow-scripts 和 allow-same-origin:除非完全信任
  3. 设置 title 属性:为 iframe 提供无障碍标签
  4. 使用 referrerpolicy:控制引荐信息泄露
  5. 测试嵌入内容:确保第三方 iframe 不会影响页面安全

最佳实践

  • 对所有 iframe 使用 sandbox 限制
  • 使用 CSP frame-ancestors 或 X-Frame-Options 防止点击劫持
  • 使用 allow 属性按需授予权限
  • 为 iframe 提供 title 属性
  • 使用 referrerpolicy 限制引荐信息
  • 加载不可信 iframe 时使用 loading="lazy"

下一节

继续学习:表单安全

参考链接