)
文档教程后端【免费下载链接】nodebestpractices✅ The Node.js best practices list (July 2026)项目地址https://gitcode.com/GitHub_Trending/no/nodebestpractices点击查看免费下载eval()、setTimeout()、setInterval()与new Function()这四类全局函数会接受字符串并将其当作 JavaScript 代码执行一旦不可信的用户输入流入这些函数攻击者就可能在服务器上执行任意命令导致整台服务器被攻陷。本文以 nodebestpractices 仓库的 Avoid JS eval statements 为核心结合仓库内 lintrules、childprocesses、sandbox 等姊妹篇文档系统讲解动态代码执行的风险原理、真实攻击样本、代码重构方案以及用 ESLint 安全插件自动化拦截的手段读完你将具备识别并消除 Node.js 项目中 eval 类隐患的实战能力。为什么这四个函数如此危险eval()、setTimeout()、setInterval()和new Function()都是 Node.js 中常见的全局函数它们有一个共同特征接受一个字符串参数并将其解析为 JavaScript 表达式、语句或语句序列后执行。问题在于这种把字符串当代码跑的能力一旦与不可信的用户输入相遇就会演变成远程代码执行RCE攻击者可以通过请求参数、请求体、Header、文件上传内容等途径把精心构造的字符串注入服务端服务器在毫不知情的情况下把这段字符串当作自己的代码执行由于 Node.js 进程通常具有较高的运行权限攻击者实际上获得了与你的应用同等甚至更高的操作能力——读写文件、发起网络请求、执行系统命令、窃取环境变量中的密钥无所不能。正如仓库文档所强调的评估用户代码实质上等于允许攻击者执行任何你当前进程可以执行的操作。因此文档给出的核心建议是重构代码使其不依赖这些函数的字符串执行能力尤其要杜绝将用户输入直接传给这些函数。真实攻击样本从一行 eval 到服务器沦陷仓库给出了一个极具冲击力的攻击示例展示攻击者只需注入一行字符串就能在服务器上执行破坏性系统命令// 攻击者成功注入的恶意代码示例 const userInput require(child_process).spawn(rm, [-rf, /]); // 恶意代码被执行 eval(userInput);这段代码的含义拆解如下攻击者输入的字符串是require(child_process).spawn(rm, [-rf, /])require(child_process)引入 Node.js 的子进程模块.spawn(rm, [-rf, /])启动系统命令rm -rf /即递归、强制删除根目录下所有文件eval(userInput)把这行字符串当作真实 JavaScript 代码执行。一旦这条路径被触发轻则文件系统被破坏重则整个服务与数据全部丢失。类似的攻击面同样存在于其他三个函数// setTimeout / setInterval 在第一个参数为字符串时同样会执行代码 setTimeout(require(child_process).exec(whoami), 100); // new Function 动态构造并调用函数 const fn new Function(return process.env); console.log(fn());关于setTimeout与setInterval需要特别说明只有当第一个参数是字符串时它才会被当作代码执行等价于间接使用 eval如果第一个参数是函数引用则不存在此风险。实践中许多开发者不知道这一点随手把用户可控的字符串塞进定时器同样会埋下 RCE 隐患。为什么这段代码这么容易进入生产环境从仓库的 avoid_publishing_secrets、escape-output 等安全章节可以看到Node.js 服务端常见的漏洞成因往往不是某个单一缺陷而是**用户输入 动态执行/动态拼接的组合**模板渲染时把用户输入直接拼进代码字符串需要灵活加载模块而把变量路径传给require()详见 safemoduleloading为了性能或便利性用 eval 解析 JSON 或运算表达式在命令行拼接时直接使用未净化输入详见 childprocesses。任何一个环节出现用户输入 eval 类函数的组合都会复现上述攻击链路。如何安全地重构替代 eval 的工程化方案仓库文档的最终建议是重构代码、彻底摆脱对 eval 类函数的依赖。下面给出可落地的替代思路1. 解析 JSON 用JSON.parse而非 eval// ❌ 危险eval 解析 JSON 等于把任意代码放进执行器 const data eval(( userInput )); // ✅ 安全JSON.parse 只解析数据不执行代码 const data JSON.parse(userInput);2. 动态函数用显式分支或查找表替代// ❌ 危险根据用户输入拼出函数名再执行 const fn new Function(a, b, userInput); // ✅ 安全用映射表限定可执行的范围 const handlers { add: (a, b) a b, mul: (a, b) a * b, }; const result handlers[userInput] ? handlersuserInput : null;3. 定时器始终传函数引用绝不传字符串// ❌ 危险字符串参数会被当作代码执行 setTimeout(doSomething( userInput ), 1000); // ✅ 安全传函数引用 setTimeout(() doSomething(sanitizedInput), 1000);4. 需要执行不可信代码时用沙箱隔离而非 eval如果业务确实要求动态执行外部传入的 JavaScript例如自定义插件、用户脚本仓库的 sandbox 章节给出了三种隔离思路独立子进程快速实现信息隔离但需要驯服子进程、限制其执行时间并处理错误恢复云 ServerlessFaaS满足沙箱各项要求但动态部署与调用成本高npm 沙箱库如sandbox、vm2一行代码即可在受限环境中执行代码简单但防护能力有限。const Sandbox require(sandbox); const s new Sandbox(); // 语法错误被拦截而不是抛到主进程 s.run(lol)hai, (output) { console.log(output); // outputSyntax error }); // 受限环境下访问不到 process s.run(process.platform, (output) { console.log(output); // outputNull }); // 死循环被超时机制终止 s.run(while (true) {}, (output) { console.log(output); // outputTimeout });注意沙箱只是降级风险而非消除风险最稳妥的策略仍然是只运行自己信任的 JavaScript 文件。5. 涉及系统命令时绝不拼接用户输入仓库 childprocesses 章节警告把未净化的用户输入传给exec()等子进程函数可能触发任意命令执行例如输入 rm -rf --no-preserve-root /。对应检查清单为能避免就完全避免用户输入进入系统命令否则必须先校验与净化并以低权限用户/组身份运行进程必要时在隔离环境中运行。用 ESLint 安全插件自动拦截 eval 类代码手动审查难免遗漏仓库 lintrules 章节推荐使用eslint-plugin-security等安全插件把禁止动态 eval固化为自动化规则。其中与本文主题直接相关的是detect-eval-with-expression规则// eslint-plugin-security 规则detect-eval-with-expression const userinput req.body.userinput; eval(userinput); // ⚠️ 触发告警eval 使用非字面量变量参数在真实项目上运行该插件终端会输出类似下方的检测结果把eval使用变量作为执行内容的高危风险直接标红除detect-eval-with-expression外该插件还能检测crypto.pseudoRandomBytes非密码学强随机数、fs.readFile的非字面量文件名参数、new RegExp构造的不安全正则等隐患配合 git hooks如pre-git可以在代码提交前强制拦截将风险挡在 CI 与生产环境之外。// 在 ESLint 配置中启用安全规则 { plugins: [security], rules: { security/detect-eval-with-expression: error, security/detect-eval-with-member-expression: error } }防御纵深把不执行不可信代码变成工程习惯综合仓库 security 目录下的多篇实践规避 eval 类风险不应只靠不写 eval而应建立多层防御习惯输入即危险默认所有外部输入都不可信永远不要直接进入代码执行路径静态代替动态能用查找表、分支、JSON.parse解决的绝不用 eval /new Function能用函数引用传给定时器的绝不传字符串工具化拦截用eslint-plugin-security把动态执行检测设为 error 级别配合 git hooks 在提交前阻断隔离兜底确实需要执行外部脚本时用子进程或沙箱库限制权限与资源并假设沙箱可能被突破来设计周边防护模块加载固定路径参照 safemoduleloadingrequire()/import一律使用静态字面量路径拒绝来自用户输入的变量路径。正如安全专家 Liran Tal 在《Essential Node.js Security》一书中所言仓库 avoideval.md 引用eval() 函数或许是 JavaScript 从安全视角看最受诟病的部分。它把 JavaScript 字符串作为文本解析再当作 JavaScript 代码执行。把不受信任的用户输入与 eval() 混在一起是一场可能以服务器被攻陷收场的灾难。这句话精准概括了本文的核心结论eval 类函数本身不是不能用而是绝不能与不可信输入相遇。对生产级 Node.js 服务而言最稳妥的策略就是把动态代码执行从代码库里彻底移除并用自动化工具守住这条红线。更多相关实践可继续阅读仓库的 lintrules、childprocesses、sandbox 与 safemoduleloading 等安全章节。赞分享文档教程后端【免费下载链接】nodebestpractices✅ The Node.js best practices list (July 2026)项目地址https://gitcode.com/GitHub_Trending/no/nodebestpractices点击查看免费下载相关推荐Node.js 安全实践彻底规避 eval 与动态代码执行nodebestpractices 安全指南Node.js 安全实践彻底规避 eval 与动态代码执行nodebestpractices 安全指南 导读 在 Node.js 服务端代码中 eval文档教程后端Node.js 沙箱安全实践在 nodebestpractices 指南中隔离运行不可信代码Node.js 沙箱安全实践在 nodebestpractices 指南中隔离运行不可信代码 本篇技术指南聚焦 Node.js 项目中一个现实且棘手的安全问题文档教程后端Front-End-Checklist 安全规则解析全面禁止 eval() 与不安全动态代码执行Front End Checklist 安全规则解析全面禁止 eval 与不安全动态代码执行 导读 本篇文章以 skills/avoid eval/refer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考