空 sandbox 属性启用全部限制:js 不执行、表单不提交、弹窗失效、localstorage 不可读写,仅 postmessage 可用;需显式添加 allow-scripts 等白名单 token 才能放行对应能力。

不加值的 sandbox 就是“全锁死”状态,JS 不执行、表单不提交、弹窗失效、localStorage 读不到——想让它干点事,必须显式加白名单 token。
空 sandbox 属性到底禁用哪些能力?
写成 <iframe src="xxx" sandbox></iframe> 或 <iframe src="xxx" sandbox=""></iframe>,浏览器会立即启用全部限制:
-
script执行被拦截(alert()、fetch()、事件监听器全失效) -
<form></form>提交静默失败(按钮点击无反应,控制台也不报错) -
window.open()、target="_blank"被阻止 -
localStorage、sessionStorage、cookie均不可读写 -
postMessage仍可用,但接收方需注意 origin 验证(沙盒不影响跨域通信本身)
常用白名单 token 怎么选?关键看你要放行什么
每个 token 控制一项具体能力,多个用空格分隔。生产环境最常组合的是:
-
allow-scripts:必须加,否则 JS 完全不运行;但加了也不代表能访问父页面 DOM(sandbox 的 DOM 隔离是强制的) -
allow-forms:只在 iframe 内有<form></form>且需提交时才加 -
allow-same-origin:仅当 iframe 与父页同源时才生效;若不同源,该 token 会被浏览器忽略;和allow-scripts同时存在,才能让脚本读写自身 origin 的localStorage -
allow-popups:需要window.open()或target="_blank"时才加;Chrome 89+ 还支持allow-downloads(配合download属性) - 慎用
allow-top-navigation:它允许 iframe 直接跳转整个页面,极易被用于钓鱼;改用allow-top-navigation-by-user-activation更安全(仅响应用户点击)
为什么 allow-same-origin 有时加了也没用?
这个 token 有两个硬性前提,缺一不可:
- iframe 的
src必须与父页面同协议、同域名、同端口(严格同源) - 不能和空
sandbox共存——比如sandbox="allow-same-origin"是合法的,但sandbox="" allow-same-origin是无效写法(属性值只能有一个) - 即使满足上述条件,iframe 内脚本仍无法访问
window.parent或document,这是 sandbox 的底层隔离机制,无法绕过
验证是否生效,可在控制台执行:document.querySelector('iframe').sandbox,返回字符串即当前实际生效的 token 列表。
安全配置容易被忽略的三个细节
很多团队配完 sandbox 就以为万事大吉,但真实线上问题往往出在边界场景:
- 动态插入的 iframe(比如 React 中用
dangerouslySetInnerHTML渲染)可能漏掉sandbox属性,导致未受控内容直接执行脚本 - 后端模板渲染时,若用变量拼接 sandbox 值(如 Django 的
{{ sandbox_tokens }}),需确保空格分隔逻辑正确,避免变成allow-scriptsallow-forms(少空格 → 浏览器识别失败) -
sandbox不替代 CSP;建议同时配置Content-Security-Policy: frame-src 'self'; script-src 'self',形成纵深防御
真正安全的沙盒不是“开了就行”,而是每次加 token 都问一句:这个能力,此刻真的必要吗?










