应避免使用 new Function,改用策略表、Map 或安全模板引擎;必须使用时需沙箱隔离、白名单校验并嵌入 CI/CD 审计。

动态生成函数(new Function)在 JavaScript 中虽灵活,但会绕过静态分析、延长作用域生命周期、阻断 V8 优化,并可能引入代码注入风险。解决其内存驻留与安全审计难题,关键在于**避免直接拼接字符串执行、显式管理执行上下文、替换为更可控的替代方案,并在构建流程中嵌入检测机制**。
识别并拦截高风险使用模式
先明确哪些用法真正危险:传入用户输入、拼接未校验变量、在循环或闭包中反复创建且未销毁引用。这类行为极易造成内存长期驻留(V8 无法回收闭包捕获的上下文)和审计盲区(AST 工具无法解析运行时构造的函数体)。
- 禁止将
userInput、localStorage值、URL 参数等未经清洗的数据直接传入new Function构造参数 - 禁用多参数形式(如
new Function('a', 'b', 'return a + b')),因其参数名易被混淆,不利于 AST 扫描 - 在 ESLint 配置中启用
no-implied-eval并自定义规则,匹配/new\s+Function\s*\(/i模式并标记为 error
用结构化表达式替代字符串求值
多数业务场景并不真正需要“动态函数”,而是需要“动态逻辑”。应优先转向类型安全、可审计、可调试的替代方式:
- 计算逻辑 → 使用 预定义策略表 + 字段映射,例如:
{ add: (a, b) => a + b, multiply: (a, b) => a * b },通过键名查表调用 - 条件组装 → 使用 对象字面量 + 解构 或 Map 结构,避免拼字符串构造分支
- 模板渲染 → 替换为 安全沙箱模板引擎(如
mustache、handlebars)或现代框架的响应式绑定(Vue/React 的 JSX/模板编译器已做静态检查)
若必须使用,严格控制生命周期与执行环境
极少数场景(如低代码公式引擎、DSL 解释器)确实需动态函数,此时必须施加硬性约束:
- 执行后立即 解除对返回函数的引用,并在
setTimeout或requestIdleCallback中主动触发 GC 友好清理(如清空缓存 Map) - 将
new Function封装进独立沙箱上下文(如VM2或isolated-vm),禁止访问全局window、eval、require等敏感 API - 对生成函数的源码做白名单正则校验(如仅允许
[\w\s\+\-\*\/\(\)\[\]\.\,\{\}\:\;]+),拒绝含;、function、import、eval等关键字的字符串
在 CI/CD 中嵌入自动化审计环节
单靠开发自觉不可靠,需把检测变成门禁:
- 在构建脚本中调用
jscodeshift或自定义 Babel 插件,扫描所有.js和.ts文件,报告new Function出现位置、调用参数是否含变量、是否在循环内 - 将结果接入 SonarQube,设置质量阈值:出现即阻断 PR 合并,除非添加
// eslint-disable-next-line no-dangerous-dynamic-function并附带安全评审说明 - 对上线后的生产代码做轻量级运行时检测(仅 dev 环境),在
Function构造器上打补丁,记录调用栈并上报异常高频调用点

















