打开网易新闻 查看精彩图片

Node.js发布了更新修复一个被描述为严重安全问题的漏洞,该漏洞影响"几乎每个生产环境的Node.js应用程序",如果成功利用,可能触发拒绝服务攻击。

Node.js的Matteo Collina和Joyee Cheung在周二的公告中表示:"Node.js/V8会尽最大努力通过可捕获的错误从栈空间耗尽中恢复,框架已经开始依赖这一机制来确保服务可用性。但是一个只有在使用async_hooks时才会出现的漏洞会破坏这种恢复尝试,当用户代码中的递归耗尽栈空间时,Node.js会直接以代码7退出,而不会抛出可捕获的错误。这使得递归深度由未经清理的输入控制的应用程序容易受到拒绝服务攻击。"

漏洞核心原理

这个缺陷的核心在于,当启用async_hooks时,如果用户代码发生栈溢出,Node.js会以代码7退出(表示内部异常处理程序运行时失败),而不是优雅地处理异常。async_hooks是一个底层的Node.js API,允许开发者跟踪异步资源(如数据库查询、定时器或HTTP请求)的生命周期。

受影响的框架和工具

Node.js表示,该问题影响多个框架和应用程序性能监控工具,包括React Server Components、Next.js、Datadog、New Relic、Dynatrace、Elastic APM和OpenTelemetry,这是因为它们使用了AsyncLocalStorage组件。AsyncLocalStorage构建在async_hooks模块之上,使得在异步操作的整个生命周期内存储数据成为可能。

修复版本

该问题已在以下版本中得到解决:

- Node.js 20.20.0(LTS)

- Node.js 22.22.0(LTS)

- Node.js 24.13.0(LTS)

- Node.js 25.3.0(当前版本)

该问题还影响从8.x版本(第一个支持async_hooks的版本)到18.x版本的所有Node.js版本。值得注意的是,代号为Carbon的Node.js 8.0.0版本于2017年5月30日发布。然而,这些版本由于已达到生命周期终止状态而保持未修补状态。

技术修复方案

修复措施检测栈溢出错误并将其重新抛给用户代码,而不是将其视为致命错误。该漏洞被追踪为CVE-2025-59466(CVSS评分:7.5)。尽管具有重大的实际影响,但Node.js表示由于以下几个原因,他们将此修复仅视为缓解措施:

- 栈空间耗尽不是ECMAScript规范的一部分

- V8 JavaScript引擎不将其视为安全问题

- "uncaughtException"处理程序的限制,该处理程序被设计为异常处理的最后手段机制

Node.js表示:"尽管这是对未指定行为的错误修复,但由于其对生态系统的广泛影响,我们选择将其纳入安全版本。React Server Components、Next.js和几乎每个APM工具都受到影响。该修复改善了开发者体验,使错误处理更加可预测。"

其他安全漏洞

除此之外,Node.js还发布了修复其他三个高危漏洞的补丁(CVE-2025-55131、CVE-2025-55130和CVE-2025-59465),这些漏洞可能被利用来实现数据泄露或损坏、使用精心制作的相对符号链接路径读取敏感文件,以及触发远程拒绝服务攻击。

鉴于漏洞的严重性,建议使用相关框架/工具和服务器托管提供商的用户尽快更新。建议库和框架的维护者应用更强大的防护措施来对抗栈空间耗尽并确保服务可用性。

Q&A

Q1:这个Node.js漏洞会影响哪些应用程序?

A:该漏洞影响几乎每个生产环境的Node.js应用程序,特别是使用React Server Components、Next.js、Datadog、New Relic、Dynatrace、Elastic APM和OpenTelemetry等框架和APM工具的应用,因为它们都使用了基于async_hooks的AsyncLocalStorage组件。

Q2:如何修复Node.js的async_hooks栈溢出漏洞?

A:用户需要将Node.js更新到修复版本,包括Node.js 20.20.0、22.22.0、24.13.0或25.3.0。修复方案会检测栈溢出错误并将其重新抛给用户代码处理,而不是直接以代码7退出程序。

Q3:为什么Node.js将这个修复视为缓解措施而不是完整解决方案?

A:Node.js认为这只是缓解措施,因为栈空间耗尽不是ECMAScript规范的一部分,V8引擎也不将其视为安全问题,加上"uncaughtException"处理程序本身的限制,使得这个修复无法完全解决根本问题。