如何修改JavaScript的new Function以支持TrustedScript且不破坏fetch类型判断
Trusted Types Polyfill:修改
new Function()的困境 我正在为Trusted Types API开发polyfill,其中一个核心功能是改造各类"注入点"的处理逻辑——比如Element.prototype.innerHTML和new Function(),让它们只接受TrustedHTML/TrustedScript类型,而非原始字符串。目前新类的polyfill已经完成,现在需要实现注入点方法的替换逻辑。
注:我严格遵循规范复刻Chromium浏览器的行为,认为这种安全性增强值得修改不受支持的内置方法,相关逻辑独立于polyfill,放在单独的
harden.js脚本中。
预期行为示例
const sanitizer = new Sanitizer(); const policy = trustedTypes.createPolicy('default', { // 用于`el.innerHTML`、`iframe.srcdoc`等场景 createHTML: input => sanitizer.sanitizeFor('div', input).innerHTML, // 用于`eval()`、`new Function()`、`script.text`等场景 createScript: () => trustedTypes.emptyScript, // 主要用于设置`script.src`/`script.setAttribute('src', src)` createScriptURL: input => /* 校验URL是否合法的逻辑 */ }); document.getElementById('foo').innerHTML = '<button onclick="alert(document.cookie)">Btn</button>'; document.getElementById('foo').innerHTML; // '<button>Btn</button>' eval('alert(location.href)'); // 无执行效果,等同于`eval('')` const func = new Function('alert(location.href)'); // 这是我需要改造的目标 func(); // 应无执行效果,和`eval()`表现一致 fetch instanceof Function; // 必须保持结果为true
当前问题
其他注入点的改造都已正常工作,但new Function()的改造陷入困境:无法在实现"支持/要求TrustedScript"的同时,保证fetch instanceof Function的判断结果为true。
失败的尝试
以下两种方案均使用createScript()方法(该方法用于检查环境支持情况、输入类型,并按需调用trustedTypes.defaultPolicy.createScript(input)),但都未达到预期:
方案1:修改Function.prototype.constructor
// 完全不生效,代码从未被调用 const func = globalThis.Function.prototype.constructor; globalThis.Function.prototype.constructor = function Function(...args) { if (args.length === 0) { return func.call(this); } else { const funcBody = createScript(args.pop()); return func.apply(this, [...args, funcBody.toString()]); } };
方案2:继承原生Function类
// 破坏了`fetch instanceof Function`的判断结果 const NativeFunction = globalThis.Function; globalThis.Function = class Function extends NativeFunction { constructor(...args) { if (args.length === 0) { super(); } else { const funcBody = createScript(args.pop()); super(...args, funcBody.toString()); } } };
核心诉求
我需要修改new Function()的行为,使其支持/要求传入TrustedScript,同时不能破坏fetch instanceof Function这类原生函数的类型判断。其他注入点只需修改方法或setter即可实现,但new Function()是构造函数,我不知道如何在不改动Function本身的前提下完成改造。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

