一、风险与目标风险:同源脚本共享上下文污染、消息注入、权限过宽、资源误用与数据泄露。目标:隔离执行环境、收敛可用能力、严格来源与消息校验、可控创建与销毁。
二、iframe隔离<iframe id="app-frame" src="/sandbox.html" sandbox="allow-scripts" referrerpolicy="no-referrer" allow="geolocation 'none'; microphone 'none'; camera 'none'"></iframe>
const frame = document.getElementById('app-frame') as HTMLIFrameElement
const origin = 'https://example.com'
function sendToFrame(msg: { type: string; payload?: any; version: number }) {
frame.contentWindow?.postMessage(msg, origin)
}
function onFrameMessage(ev: MessageEvent) {
if (ev.origin !== origin) return
const m = ev.data as { type: string; payload?: any; version: number }
if (typeof m?.type !== 'string' || typeof m?.version !== 'number') return
}
window.addEventListener('message', onFrameMessage)
三、Worker隔离const worker = new Worker('/worker.js', { type: 'module' })
function sendToWorker(msg: { type: string; payload?: any; version: number }) {
worker.postMessage(msg)
}
worker.onmessage = ev => {
const m = ev.data as { type: string; payload?: any; version: number }
if (typeof m?.type !== 'string' || typeof m?.version !== 'number') return
}
function stopWorker() { worker.terminate() }
四、MessageChannel与类型守卫const ch = new MessageChannel()
function isMsg(x: any): x is { type: string; payload?: any; version: number } {
return x && typeof x.type === 'string' && typeof x.version === 'number'
}
function connectWithChannel(target: Window, origin: string) {
target.postMessage({ type: 'connect', version: 1 }, origin, [ch.port2])
ch.port1.onmessage = ev => { if (isMsg(ev.data)) {} }
}
五、策略协同Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; frame-ancestors 'none'
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
六、验收清单iframe使用`sandbox`且最小能力集合,不授予`allow-same-origin`除非必要。Worker独立执行且通信仅接受满足类型守卫的消息。`postMessage`严格校验`origin`与结构,使用固定`version`与有限`type`枚举。CSP限制默认来源与可连接端点;COOP/COEP提升隔离与资源嵌入安全性。建立创建与销毁流程,空闲时终止Worker并释放资源。

发表评论 取消回复