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