CVE-2025-50537CVE-2025-50537是存在于eslint(一个广泛使用的JavaScript代码检查工具)9.26.0之前版本中的一个栈溢出漏洞。该漏洞位于eslint/lib/shared/serialization.js文件的序列化功能中,当处理包含循环引用的JavaScript对象时,isSerializable()函数会进入无限递归状态,最终导致栈溢出崩溃。攻击者可以通过eslint的RuleTester.run()方法触发此漏洞,该方法通常用于验证自定义规则的测试用例并检查重复项。在验证测试用例过程中,checkDuplicateTestCase()函数会被调用,该函数依赖isSerializable()进行序列化检查。当测试用例中包含循环引用对象时,序列化过程无法正确处理这种自引用数据结构,导致无限递归调用栈,最终造成应用程序栈空间耗尽。此漏洞的CVSS评分为5.5,属于中等严重程度,攻击向量为本地,需要用户交互,但无需认证即可利用。成功利用此漏洞可能导致使用eslint进行代码检查的应用程序崩溃,影响开发工作流程的连续性。
该栈溢出漏洞的根本原因在于eslint/lib/shared/serialization.js中的isSerializable()函数缺乏对循环引用的检测和正确处理机制。在JavaScript中,对象可以包含对自身的引用(循环引用),例如:const obj = {}; obj.self = obj; 当isSerializable()函数尝试序列化这样的对象时,它会递归地遍历对象的所有属性。由于obj.self指向obj自身,函数会再次尝试序列化obj,从而陷入无限递归循环。攻击者利用RuleTester.run()方法触发漏洞的具体流程如下:首先构造一个包含循环引用的测试用例对象;然后调用RuleTester.run()方法执行该测试用例;在内部验证过程中,checkDuplicateTestCase()函数调用isSerializable()进行序列化检查;由于循环引用的存在,isSerializable()进入无限递归状态;最终调用栈深度超出JavaScript引擎的限制,导致栈溢出错误。漏洞利用的关键在于循环引用对象能够绕过isSerializable()函数的递归终止条件。由于每次递归调用都会在栈上分配新的栈帧,且函数没有深度限制检查或循环引用检测机制,因此递归调用会持续进行直到栈空间耗尽。在Node.js环境中,这通常会导致进程崩溃并抛出RangeError: Maximum call stack size exceeded错误。攻击者可以通过精心构造的测试用例或插件配置来触发此漏洞,影响任何使用eslint进行代码验证的系统。