oscerd/CVE-2026-46455
GitHub: oscerd/CVE-2026-46455
该项目复现了 Apache camel-keycloak 因缺失 TokenVerifier.IS_ACTIVE 检查而接受过期 access token 的身份验证绕过漏洞(CVE-2026-46455)。
Stars: 0 | Forks: 0
# camel-keycloak 缺少 IS_ACTIVE 检查 — 接受过期 Token 复现程序 (CVE-2026-46455)
本项目演示了 Apache Camel 的 `camel-keycloak` 组件中的一个**身份验证弱点**,追踪编号为
**CVE-2026-46455**。安全辅助类 `KeycloakSecurityHelper.parseAndVerifyAccessToken` 构建了一个 Keycloak
`TokenVerifier`,并在 `withChecks(...)` 中仅使用了**主体存在**和**realm-URL (issuer)** 检查。
Keycloak 的 `TokenVerifier.withChecks(...)` 会追加到一个*初始为空*的检查列表中 —— 上游默认的
检查仅通过 `withDefaultChecks()` 安装 —— 因此内置的 **`IS_ACTIVE`** 断言(用于验证
token 的 `exp` / `nbf` 声明)**从未被应用**。因此,该辅助类验证了签名、主体和
issuer,但**并未强制执行 token 的有效期**:一个**已过期的**(或尚未生效的)access token 会被
当作有效 token 接受。
安全公告:https://camel.apache.org/security/CVE-2026-46455.html
## 漏洞概述
| 属性 | 值 |
|----------|-------|
| **组件** | `camel-keycloak` |
| **受影响类** | `org.apache.camel.component.keycloak.security.KeycloakSecurityHelper#parseAndVerifyAccessToken` |
| **CWE** | CWE-613 (会话过期不充分) + CWE-287 (身份验证不当) |
| **影响** | 接受过期 / 尚未生效的 access token → 请求在 token 生命周期之外通过身份验证 |
| **受影响版本** | 4.18.0 至 4.18.3 之前,4.19.0 至 4.21.0 之前 (辅助类于 4.18.0 引入;4.14.x LTS 不受影响) |
| **已修复版本** | 4.18.3, 4.21.0 |
| **JIRA** | CAMEL-23504 |
| **报告者** | Andrea Cosentino (Apache Software Foundation) 和 Yu Bao (PayPal) |
## 技术细节
```
// KeycloakSecurityHelper.parseAndVerifyAccessToken(...) - affected 4.18.2
TokenVerifier verifier = TokenVerifier.create(tokenString, AccessToken.class)
.publicKey(publicKey)
.withChecks(
TokenVerifier.SUBJECT_EXISTS_CHECK,
new TokenVerifier.RealmUrlCheck(expectedIssuer)); // <-- no TokenVerifier.IS_ACTIVE
AccessToken token = verifier.verify().getToken();
```
`withChecks(...)` 从一个空列表开始,因此 `IS_ACTIVE`(即 `exp`/`nbf` 有效期检查)并未运行。
修复方案 (4.18.3 / 4.21.0) 在 `withChecks(...)` 调用中添加了 `TokenVerifier.IS_ACTIVE`,从而拒绝
过期 / 尚未生效的 token。
## PoC 的工作原理
该辅助类直接获取公钥,因此**不需要 Keycloak 服务器**。`/exploit/attack`
endpoint:
1. 生成一对 RSA 密钥;
2. 铸造一个正确签名的 Keycloak `AccessToken`,它具有正确的 issuer 和主体,但其 `exp`
是**30 分钟前**;
3. 调用 `KeycloakSecurityHelper.parseAndVerifyAccessToken(...)` —— 在受影响的版本中,它会**接受**
该过期 token;
4. 在添加了 `TokenVerifier.IS_ACTIVE`(即修复方案所做的工作)后重新验证同一个 token —— 此时该 token 会被**拒绝**。
```
CVE-2026-46455/
├── pom.xml # camel-keycloak 4.18.2 + keycloak-core 26.0.8
├── Dockerfile
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ └── ExploitController.java # mints an expired token and verifies it via the helper
└── resources/
└── application.properties
```
## 前置条件
- Java 17+ 和 Maven 3.8+
- Docker (用于运行复现程序)
## 复现步骤
### 步骤 1:构建并启动容器
```
mvn clean package -DskipTests
docker compose up -d --build
```
### 步骤 2:触发检查
```
curl -s http://localhost:8080/exploit/attack
# -> 铸造了一个已正确签名的 access token,该 token 在 30 分钟前过期 (...).
# # KeycloakSecurityHelper.parseAndVerifyAccessToken -> ACCEPTED (返回了 subject 为 'attacker-user' 的 token)
# 使用 TokenVerifier.IS_ACTIVE 的相同 token (修复方案) -> 被拒绝 (已过期)
# # >>> 身份验证绕过证明 — helper 接受了一个已被 IS_ACTIVE 拒绝的过期 token: true
```
### 清理
```
docker compose down
```
## 攻击向量
任何通过 `KeycloakSecurityHelper.parseAndVerifyAccessToken`(例如
通过 `KeycloakSecurityPolicy`)对入站请求进行身份验证的路由都会接受超出其预期生命周期的 access token —— 一个已经过期
(或者在依赖 `exp` 的情况下,超过其自然过期时间被吊销)的 token 仍然会被视为有效。
## 利用条件
1. 路由在受影响的版本上使用 camel-keycloak 的安全 helper 来验证 access token。
2. 一个由预期的 issuer 有效签名,但其有效期已过的 access token。
## 推荐修复方案
升级至 **4.18.3 / 4.21.0** (CAMEL-23504),这些版本添加了 `TokenVerifier.IS_ACTIVE`,从而拒绝
过期 / 尚未生效的 token。
## 缓解措施
在升级之前:
1. 在信任 access token 之前,在路由中验证其 `exp` / `nbf` 声明。
2. 保持 Keycloak 的 access token 生命周期较短。
3. 确保任何上游网关或资源服务器也强制执行 token 有效期。
## 免责声明
此复现程序仅用于**安全研究和授权测试**,针对的是一个**已公开披露且已修复的**
漏洞。未经明确许可,请勿将其用于攻击系统。
标签:Apache Camel, JS文件枚举, Keycloak, OAuth/JWT, 域名枚举, 漏洞复现, 请求拦截