只读描述符无法拦截恶意脚本对微任务基类的直接破坏,因其可被delete+重定义、reflect.setprototypeof或污染全局引用绕过;有效防御需冻结原型、缓存原生引用并封装调用、使用web worker隔离,配合csp与sandbox等平台级约束。

无法通过只读描述符拦截恶意脚本对微任务核心基类(如 Promise、queueMicrotask 或自定义基类)的直接破坏。
只读描述符本身不构成运行时防护
JavaScript 的 Object.defineProperty 设置 writable: false 仅在非严格模式下阻止赋值,在严格模式下抛出错误——但该限制可被轻易绕过:
- 恶意脚本可直接删除属性再重新定义:
delete Promise.resolve; Promise.resolve = hackedFn; - 可通过
Reflect.setPrototypeOf修改原型链,替换整个构造函数行为 - 可篡改
Promise.constructor或污染全局self引用,使描述符失效
真正有效的防御是运行时隔离与重写保护
针对微任务基类的篡改,应放弃“锁属性”思路,转向更鲁棒的机制:
-
冻结关键构造器原型:在页面早期执行
Object.freeze(Promise.prototype),阻止方法覆盖(注意:不能冻结Promise构造函数自身,但可冻结其不可枚举的关键方法) -
缓存原始引用并封装调用:在任何第三方脚本加载前,保存原生函数:
const nativeQueue = queueMicrotask;,后续所有微任务调度统一走封装层,校验调用上下文 -
使用
vm.Context或Web Worker隔离敏感逻辑:将核心业务逻辑(如支付确认、签名生成)移入独立上下文,主页面仅传递指令,避免基类暴露在污染环境中
配合 CSP 与 sandbox 环境收口
单靠 JS 层面的描述符或冻结无法对抗插件级篡改。必须叠加平台级约束:
- 启用
Content-Security-Policy: script-src 'self'; object-src 'none',禁止内联脚本和 eval,大幅压缩篡改入口 - 对嵌入的 iframe 使用
sandbox="allow-scripts"并移除allow-same-origin,防止子帧污染主环境 - 在 WebView2 等嵌入场景中,启用
CoreWebView2Settings.IsScriptEnabled = true但禁用IsWebViewScriptApisEnabledForServiceWorkers,切断脚本对底层微任务调度器的穿透能力










