rootdirective-sec/CVE-2026-29000-Lab
GitHub: rootdirective-sec/CVE-2026-29000-Lab
这是一个用于验证 pac4j-jwt 库 CVE-2026-29000 认证绕过漏洞的 Docker 化 PoC 实验室,通过对比多版本行为差异证明攻击者可伪造任意身份声明。
Stars: 0 | Forks: 0
# CVE-2026-29000 — pac4j-jwt 库级 PoC 实验室
## TL;DR
本仓库包含 `pac4j-jwt` 中 **CVE-2026-29000** 的一个**库级 PoC**。
它通过两种情况对比了易受攻击版本与已修补版本的行为:
* **基线**:合法令牌应被接受
* **攻击**:伪造令牌在易受攻击版本应被接受,在已修补版本应被拒绝
| 版本 | 基线 | 攻击 | 结果 |
|---|---:|---:|---|
| `6.0.3` | ✅ | ✅ | 易受攻击 |
| `6.0.4.1` | ✅ | ✅ | 易受攻击 |
| `6.3.3` | ✅ | ❌ | 已修补 |
此 PoC 演示了在易受攻击的版本中,攻击者可以创建带有受控 subject 和 roles 的已认证配置文件 (authenticated profile),而已修补版本会拒绝该伪造令牌。
## 本项目是什么
这**不是**一个 Web 应用程序演示。
它是一个小型 Java 程序,直接调用 `JwtAuthenticator` 并在 Docker 内部对比 `pac4j-jwt` 的多个版本。
目标是证明三件事:
1. 合法令牌仍然有效
2. 易受攻击版本接受了伪造的攻击者可控声明 (claims)
3. 已修补版本拒绝了伪造的攻击者可控声明
## 为何选择这些版本
测试版本是经过慎重选择的:
* **6.0.3** — 选用是因为一份公开的技术文章报告称该版本存在有效的 PoC
* **6.0.4.1** — 选用是因为公开的公告数据将其置于受影响的 6.x 范围内
* **6.3.3** — 选用是因为它是 6.x 系列的修复版本
这为实验室提供了三个有用的参考点:
* 一个公开 PoC 的参考版本
* 一个经公告确认的受影响版本
* 一个已修补版本
## 项目结构
```
.
├── docker-compose.yml
├── Dockerfile
├── pom.xml
└── src/main/java/lab/Repro.java
```
### 文件作用
* `docker-compose.yml`
定义每个版本的测试矩阵。
* `Dockerfile`
在容器内构建并运行 PoC。
* `pom.xml`
定义依赖项并构建一个可运行的 fat JAR。
* `src/main/java/lab/Repro.java`
实际的 PoC 利用程序。
## 服务的含义
`docker-compose.yml` 文件定义了三个服务:
* `v603` = 测试 `pac4j-jwt 6.0.3`
* `v6041` = 测试 `pac4j-jwt 6.0.4.1`
* `patched` = 测试 `pac4j-jwt 6.3.3`
因此这些命令的意思是“针对该特定版本运行一次 PoC”:
```
docker compose run --rm v603
docker compose run --rm v6041
docker compose run --rm patched
```
`--rm` 意味着运行结束后临时容器会被移除。
## 如何运行
### 构建
```
docker compose build --no-cache
```
### 运行
```
docker compose run --rm v603
docker compose run --rm v6041
docker compose run --rm patched
```
## PoC 做了什么
对于每个版本,程序运行两种情况。
### 1) 基线 (Baseline)
它生成一个合法令牌并通过 `JwtAuthenticator` 对其进行验证。
预期结果:
* 在所有测试版本中被接受
### 2) 攻击 (Attack)
它生成一个带有攻击者可控声明的伪造令牌,并通过 `JwtAuthenticator` 对其进行验证。
预期结果:
* 易受攻击版本 → 伪造身份被接受
* 已修补版本 → 伪造令牌被拒绝
## 如何解读输出
### 易受攻击版本输出
你应该会看到类似这样的内容:
```
[case] baseline
result: ACCEPTED
observed_subject: alice
observed_roles: [ROLE_USER]
[case] attack
result: ACCEPTED
observed_subject: admin#override
observed_roles: [ROLE_SUPERUSER, ROLE_ADMIN]
[summary]
conclusion: VULNERABLE: forged token accepted
```
含义:
* 正常令牌有效
* 伪造令牌也被接受
* subject 和 roles 被替换为攻击者控制的值
### 已修补版本输出
你应该会看到类似这样的内容:
```
[case] baseline
result: ACCEPTED
observed_subject: alice
observed_roles: [ROLE_USER]
[case] attack
result: REJECTED
reason: CredentialsException: A non-signed JWT cannot be accepted as signature configurations have been defined
[summary]
conclusion: PATCHED: forged token rejected
```
含义:
* 正常令牌有效
* 伪造令牌被拒绝
* 已修补版本不再接受攻击所使用的未签名内部 JWT 路径
## 为什么这个仓库关注库行为而不是通用令牌脚本
此 CVE 影响的是**库级认证路径**,而不是具有单一通用角色模型的应用程序。
可复用的是**攻击形态 (attack shape)**:
* 伪造攻击者可控声明
* 加密为 JWE
* 传递给 `JwtAuthenticator`
在实际应用程序中**非通用**的部分:
* 声明名称
* 角色名称
* 授权映射
* 密钥材料 / JWKS 设置
* 特定于应用程序的配置文件处理
因此,本仓库侧重于证明该库在易受攻击版本上接受伪造的攻击者可控声明,而不是假装存在一个能自动适用于任意应用程序的通用令牌。
## 截图
1. `docker compose run --rm v603`
2. `docker compose run --rm v6041`
3. `docker compose run --rm patched`
### 易受攻击版本:6.0.3

### 易受攻击版本:6.0.4.1

### 已修补版本:6.3.3

## 参考资料
* [pac4j security advisory for JwtAuthenticator](https://www.pac4j.org/blog/security-advisory-pac4j-jwt-jwtauthenticator.html)
* [GitHub Advisory Database: CVE-2026-29000](https://github.com/advisories/GHSA-pm7g-w2cf-q238)
* [NVD entry: CVE-2026-29000](https://nvd.nist.gov/vuln/detail/CVE-2026-29000)
* [CodeAnt technical write-up: public-key authentication bypass PoC](https://www.codeant.ai/security-research/pac4j-jwt-authentication-bypass-public-key)
## 最终总结
本项目演示了三个核心事实:
1. 合法基线令牌在所有测试版本上均被接受
2. 伪造的攻击者可控声明在 `6.0.3` 和 `6.0.4.1` 上被接受
3. 伪造的攻击者可控声明在 `6.3.3` 上被拒绝
这是本仓库中针对此 CVE 的易受攻击与已修补对比的核心证据。
在易受攻击的版本上,伪造的令牌不仅仅是被解析——它生成了一个带有攻击者控制的 subject 和 roles 的已认证配置文件。
标签:CVE-2026-29000, Docker, JSON Web Token, JS文件枚举, JWT, pac4j-jwt, PoC, 依赖库安全, 协议分析, 域名枚举, 安全测试, 安全漏洞, 安全防御评估, 攻击性安全, 暴力破解, 权限提升, 概念验证, 漏洞分析, 漏洞复现, 认证绕过, 请求拦截, 路径探测