Skip to content

iframe 安全属性(sandbox / allow)

iframe 的安全是 Web 开发中的重要议题。HTML5 通过 sandboxallow 属性提供了精细的权限控制机制。本节将深入讲解这两个安全属性的用法和最佳安全实践。

前置知识

阅读本节前,建议先了解:iframe 内联框架

基础概念

嵌入第三方内容(如广告、用户评论、小部件)时,iframe 可能成为安全风险的入口。攻击者可能利用 iframe 进行点击劫持(Clickjacking)、恶意脚本注入等攻击。

HTML5 提供了两层安全控制:sandbox 属性对 iframe 内容施加功能限制;allow 属性控制 iframe 可以使用的浏览器特性(如摄像头、麦克风、地理位置等)。这两个属性配合使用,可以精确控制 iframe 的权限范围。

语法

sandbox 属性

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>sandbox</title>
</head>
<body>
  <h1>sandbox 属性</h1>

  <!-- 空 sandbox:应用最严格的限制 -->
  <iframe src="untrusted.html"
          sandbox
          title="不可信内容"></iframe>

  <!-- 允许脚本执行 -->
  <iframe src="widget.html"
          sandbox="allow-scripts"
          title="带脚本的组件"></iframe>

  <!-- 允许脚本和表单提交 -->
  <iframe src="comment.html"
          sandbox="allow-scripts allow-forms"
          title="评论组件"></iframe>
</body>
</html>

allow 属性

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>allow 属性</title>
</head>
<body>
  <h1>allow 属性</h1>

  <!-- 允许使用摄像头和麦克风 -->
  <iframe src="video-call.html"
          allow="camera; microphone"
          title="视频通话"></iframe>

  <!-- 允许全屏和自动播放 -->
  <iframe src="media-player.html"
          allow="fullscreen; autoplay"
          title="媒体播放器"></iframe>

  <!-- 允许地理位置和剪贴板 -->
  <iframe src="location-app.html"
          allow="geolocation; clipboard-read; clipboard-write"
          title="位置应用"></iframe>
</body>
</html>

详细说明

sandbox 值详解

作用风险等级
(空)最严格限制,禁止一切最安全
allow-scripts允许 JavaScript 执行中等
allow-forms允许表单提交
allow-same-origin允许视为同源
allow-popups允许打开弹窗
allow-top-navigation允许导航父页面
allow-modals允许打开模态框
allow-downloads允许下载中等

allow-same-origin + allow-scripts 的危险组合

同时使用 allow-same-originallow-scripts 会移除沙盒的保护——iframe 可以删除自身的 sandbox 属性,恢复完整权限。仅在完全信任嵌入内容时才同时使用这两个值。

sandbox 值组合示例

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>sandbox 组合</title>
</head>
<body>
  <h1>sandbox 值组合</h1>

  <!-- 评论系统:允许脚本和表单 -->
  <iframe src="comments.html"
          sandbox="allow-scripts allow-forms allow-same-origin"
          title="评论系统"></iframe>

  <!-- 第三方广告:只允许脚本 -->
  <iframe src="ad.html"
          sandbox="allow-scripts"
          title="广告"></iframe>

  <!-- 富文本编辑器:允许脚本、表单和同源 -->
  <iframe src="editor.html"
          sandbox="allow-scripts allow-forms allow-same-origin allow-popups"
          title="编辑器"></iframe>

  <!-- 不可信内容:最严格限制 -->
  <iframe src="user-content.html"
          sandbox=""
          title="用户内容"></iframe>
</body>
</html>

allow 权限策略(Permissions Policy)

特性allow 值说明
摄像头camera允许调用摄像头
麦克风microphone允许调用麦克风
地理位置geolocation允许获取位置信息
全屏fullscreen允许全屏模式
自动播放autoplay允许自动播放媒体
加密媒体encrypted-media允许加密媒体扩展
图片/视频picture-in-picture允许画中画模式
剪贴板读clipboard-read允许读取剪贴板
剪贴板写clipboard-write允许写入剪贴板
下载downloads允许文件下载
支付payment允许支付请求 API

CSP 框架祖先(Content-Security-Policy)

html
<!--
  通过 HTTP 头控制哪些页面可以嵌入你的页面:
  Content-Security-Policy: frame-ancestors 'self' https://trusted.com;

  或者通过 meta 标签(部分 CSP 指令):
-->
<meta http-equiv="Content-Security-Policy"
      content="frame-ancestors 'self' https://partner.com;">

CSP frame-ancestors 指令用于防止你的页面被其他网站的 iframe 嵌入,防御点击劫持攻击:

效果
'none'禁止任何页面嵌入
'self'只允许同源页面嵌入
URL只允许指定域名嵌入

实战示例

安全的第三方嵌入

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>安全嵌入</title>
</head>
<body>
  <h1>安全嵌入第三方内容</h1>

  <!-- YouTube 视频嵌入(安全配置) -->
  <iframe src="https://www.youtube.com/embed/VIDEO_ID"
          sandbox="allow-scripts allow-same-origin allow-popups"
          allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
          allowfullscreen
          loading="lazy"
          width="560" height="315"
          title="视频播放器"></iframe>

  <hr>

  <!-- 用户生成的 HTML 内容(不可信) -->
  <iframe srcdoc="<p>用户提交的 HTML 内容</p>"
          sandbox=""
          title="用户内容预览"
          width="100%" height="200"></iframe>

  <hr>

  <!-- 网站分析工具 -->
  <iframe src="https://analytics.example.com/widget"
          sandbox="allow-scripts"
          allow="clipboard-read"
          title="分析面板"
          loading="lazy"
          width="300" height="400"></iframe>
</body>
</html>

注意事项

  • 空的 sandbox 属性是最安全的,禁止所有功能
  • 避免同时使用 allow-same-originallow-scripts
  • allow 属性优先于 sandbox,两者独立工作
  • 旧的 allow-* 属性(如 allowfullscreen)已被 allow` 取代
  • CSP frame-ancestors 只能通过 HTTP 头设置,不能在 <meta> 中设置
  • sandbox 不会阻止 iframe 加载资源(如图片、CSS),只限制其行为

最佳实践

  • 始终为嵌入的第三方内容添加适当的 sandbox 限制
  • 为不可信内容使用空的 sandbox 属性
  • 使用 allow 属性精确控制所需的浏览器特性
  • 在服务器端设置 CSP frame-ancestors 防止被恶意嵌入
  • 逐步放宽 sandbox 限制,从最严格开始
  • 测试 sandbox 限制是否影响 iframe 的正常功能

下一节

继续学习:embed 嵌入插件

参考链接