关联:CVE总览安全学习

0x01 漏洞描述

CVE-2025-29927 是 Next.js 框架中发现的一个严重授权绕过漏洞。该漏洞允许攻击者通过伪造特定的 HTTP 请求头,绕过中间件中的授权检查,从而未经授权地访问受保护的资源。此问题影响了使用“next start”命令并设置“output: ‘standalone’”的自托管 Next.js 应用程序。

Next.js 使用内部头字段“x-middleware-subrequest”来防止递归请求导致的无限循环。攻击者可以通过在请求中伪造该头字段,跳过中间件的执行,从而绕过关键的安全检查,例如授权 Cookie 验证。

1.1 受影响的版本

==Next.js 15.x < 15.2.3

==Next.js 14.x < 14.2.25

==Next.js 13.x < 13.5.9

1.2 影响范围

使用中间件的自托管 Next.js 应用程序(next start with output: standalone)

依赖 Middleware 进行身份验证或安全检查的应用程序,稍后不会在应用程序中进行验证

0x02 环境搭建

使用 p 神的https://github.com/vulhub/vulhub/blob/master/next.js/CVE-2025-29927/README.zh-cn.md

可以把vulhub都gitclone下来。然后进对应的文件夹docker-compose up -d

┌──(root㉿kali)-[/home/…/Desktop/vulhub/next.js/CVE-2025-29927]
└─# docker-compose up -d
Creating network "cve-2025-29927_default" with the default driver
Pulling web (vulhub/nextjs:15.2.2)...
15.2.2: Pulling from vulhub/nextjs
6e909acdb790: Pull complete
d714f4673cad: Pull complete
be84add755f8: Pull complete
9a8d89ceeab1: Pull complete
4c07c1809c8e: Pull complete
a98958ee95bc: Pull complete
23bec30f180e: Pull complete
bf031c299822: Pull complete
Digest: sha256:d4df62ece026292a8068bf48667fd8ad44b31120237ff302de294da88d7ee018
Status: Downloaded newer image for vulhub/nextjs:15.2.2
Creating cve-2025-29927_web_1 ... done
 

看到在3000端口启动了对应环境

0x03 漏洞复现

启动环境后访问you_ip:3000

自动重定向到了/login路由。

需要我们登录,我们可以输入admin:password登录。

如果我们不知道密码的情况下,可以利用该漏洞实现越权登录:

我们添加请求头(注意我们要访问的不是login路由,是根目录)

x-middleware-subrequest:middleware:middleware:middleware:middleware:middleware

可以看到成功确权访问了admin管理界面

0x04 漏洞原理

看文章Next.js 中间件鉴权绕过漏洞 (CVE-2025-29927)-先知社区

关键代码

export const run = withTaggedErrors(async function runWithTaggedErrors(params) {
const runtime = await getRuntimeContext(params)
const subreq = params.request.headers[`x-middleware-subrequest`]
const subrequests = typeof subreq === 'string' ? subreq.split(':') : []
 
const MAX_RECURSION_DEPTH = 5
const depth = subrequests.reduce(
  (acc, curr) => (curr === params.name ? acc + 1 : acc),
  0
)
 
if (depth >= MAX_RECURSION_DEPTH) {
  return {
    waitUntil: Promise.resolve(),
    response: new runtime.context.Response(null, {
      headers: {
        'x-middleware-next': '1',
      },
    }),
  }
}

会检查请求头,x-middleware-subrequest,并按:分割值。

当递归深度大于MAX_RECURSION_DEPTH = 5时,会绕过中间件的检查继续后续内容。

4.1 中间件:

Next.js中可以用于在请求到达 API 路由或页面组件之前执行全局逻辑,比如身份验证、请求拦截、重定向等。就是在执行请求前执行一些动作。(在该环境下就是在请求前进行身份验证)

4.2 x-middleware-subrequest头:

为了防止一直递归调用进入死循环而设计。比如:请求一个地址,发现没有登录,于是跳转到login,但是此时还是没有登录,于是又会调用中间件,这样会造成重复递归调用。此时有x-middleware-subrequest头,中间件检测到它,就知道这里已经检测过了,就可以跳过这次检测。

所以我们要伪造请求头x-middleware-subrequest:根据检查后面的值为中间件名,而规定中间件名为,所以我们填5个middleware即可绕过检测。

他的路径通常在根目录/middleware或者src目录/src/middleware,所有我们的payload为

x-middleware-subrequest:middleware:middleware:middleware:middleware:middleware
x-middleware-subrequest:src/middleware:src/middleware:src/middleware:src/middleware:src/middleware

【WatCTF 2025 】Waterloo Trivia Dash

答完三道题后得到一个按钮,按了没反应,于是复制连接看一下。

http://112.124.64.34:3080/admin,是一个admin路由,抓包看

访问之后会307跳转到根路由。

我们信息收集一下

发现是Next.js版本15.2.2 < 15.2.3 存在已知的漏洞。我们尝试攻击

该题的中间件是在src目录下。