You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 16:37:06