sandbox属性默认禁用所有API,alert()等静默失败;必须显式白名单授权,如allow-scripts仅放行外链脚本,localStorage需额外权限且受用户手势限制;allow-same-origin等组合会严重削弱沙箱安全性。

直接加 sandbox 属性不会“限制”敏感 API,而是默认全部禁用——alert()、fetch()、localStorage.setItem() 全部静默失败,连控制台都不报错;真要让插件跑起来,必须显式开白名单,且每开一项都得想清楚它到底要不要。
为什么写了 sandbox 却连 alert(1) 都不弹
因为 <iframe sandbox></iframe> 等价于 sandbox="",浏览器立刻进入“全锁死”状态:脚本不解析、内联事件失效、fetch() 被丢弃、表单提交无响应。这不是 JS 错了,是权限被硬拦截。
- 验证方法:控制台执行
document.querySelector('iframe').sandbox,返回空DOMTokenList []就说明没开任何权限 -
allow-scripts是起点,但只放行外链脚本(<script src="xxx.js"></script>),<script>alert(1)</script>和onclick="alert(1)"依然无效 - 动态设置
iframe.sandbox = "allow-scripts"无效,属性必须在 DOM 插入前就写死
allow-scripts 开了,为什么 localStorage 还是读写失败
因为 localStorage、sessionStorage、IndexedDB 属于“持久化存储”,默认不随 allow-scripts 一起放行——即使开了它,localStorage.length 返回 0,Object.keys(localStorage) 是空数组,DevTools 的 Application 面板显示 “(inactive)” 或空白,都是正常表现。
- 没有
allow-storage-access-by-user-activation(仅 Chrome/Edge 支持),且未由用户手势触发,就别指望存东西 - 真实场景中,应由父页托管状态,插件通过
window.parent.postMessage()上报变更 - 父页接收时必须校验
event.origin,不能只靠allow-same-origin放行
哪些权限组合实际可用,哪些会绕过沙箱
生产环境嵌第三方或用户可控插件(如广告 SDK、富文本渲染器)时,以下组合等于关掉沙箱:
立即学习“前端免费学习笔记(深入)”;
-
sandbox="allow-scripts allow-same-origin"→ 同源时可读写父页localStorage、发起同源fetch(),XSS 风险直线上升 -
sandbox="allow-top-navigation"→ 插件可执行top.location = 'https://phishing.site',整页跳转钓鱼站 -
sandbox="allow-scripts allow-same-origin allow-popups allow-forms allow-top-navigation"→ 权限堆砌,和没加sandbox几乎等效
真正安全的起点是:只开 allow-scripts,其他按需逐个加,并确认插件是否真需要它。比如广告插件只需 sandbox="allow-scripts allow-popups",表单类插件加 allow-forms 即可,allow-same-origin 在生产环境应永远避免。
沙箱不是一劳永逸的开关,它是逐项授权的清单——每多一个 token,攻击面就扩大一分;最常被忽略的是:开了 allow-scripts 后,插件仍无法访问 window.parent 或父页 DOM,这是 sandbox 的硬边界,别指望靠它实现深度集成。



















