
Runnable proof-of-concept reproducer for the Apache Camel camel-keycloak issuer validation bypass (CWE-287), demonstrating affected and patched behaviour in Spring Boot and Quarkus.
Runnable proof-of-concept reproducer for the Apache Camel vulnerability where camel-keycloak's
KeycloakSecurityProcessor validated the issuer of an introspected token only when the introspection response
actually carried an iss claim. When the claim was absent the check was skipped rather than treated as a
failure, so a token the configured issuer did not mint could be accepted — provided the introspection endpoint
answered active without naming an issuer. Where a deployment introspects against an endpoint that omits iss and
serves more than one issuer, the consequence is that it authenticates a caller it should have rejected (CWE-287).
| Runtime | Directory | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-keycloak 4.22.0 (affected; fixed 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-keycloak (Camel 4.22.0, affected; fixed control CQ 3.40.0 / Camel 4.22.1) |
Both modules demonstrate the affected and the fixed behaviour against the real KeycloakSecurityProcessor.
The driver configures a KeycloakSecurityPolicy with validateIssuer=true (expected issuer
http://localhost:8080/realms/test-realm) and a token introspector that reports the token active but returns
no iss claim — exactly what a broker/gateway introspection endpoint produces, since RFC 7662 makes iss
optional. It then drives a KeycloakSecurityProcessor with an Authorization: Bearer <attacker-token> header and
reports whether the protected route is reached.
iss makes the processor skip the issuer check, so the token is accepted and the
route is reached — a token from an unintended issuer is authenticated.iss is a validation failure; the processor throws CamelAuthorizationException
("Token issuer missing…") and the route is never reached.# Camel Spring Boot
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: route reached, token accepted; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -jar target/cve-2026-85301-keycloak-issuer-bypass-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: CamelAuthorizationException "Token issuer missing"; >>> Not exploited
# Camel Quarkus
cd camel-quarkus
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected (Camel 4.22.0): route reached, token accepted
docker compose down
# Patched control: CQ 3.40.0 ships Camel 4.22.1
mvn clean package -Dcamel-quarkus.version=3.40.0 -Dquarkus.platform.version=3.40.0
java -jar target/quarkus-app/quarkus-run.jar &
curl -s http://localhost:8080/exploit/attack # fixed: CamelAuthorizationException "Token issuer missing"
| Property | Value |
|---|---|
| Component | camel-keycloak (KeycloakSecurityProcessor.validateIssuerFromIntrospection) |
| CWE | CWE-287 (Improper Authentication) |
| Severity | MEDIUM |
| Attack vector | A token from an unintended issuer, introspected against an endpoint that omits iss and serves more than one issuer, while validateIssuer=true |
| Impact | The deployment authenticates a caller whose token the configured issuer did not mint |
| Affected Versions | From 4.15.0 before 4.18.5, from 4.19.0 before 4.22.1 |
| Fixed Versions | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24448 |
| Credit | Claude Security Scan Tool |
Advisory: https://camel.apache.org/security/CVE-2026-85301.html
The Quarkus affected module is built on CQ 3.39.0 (Camel 4.22.0), where
camel-quarkus-keycloakmaps to an affected Camel version. The patched control is CQ 3.40.0 (Camel 4.22.1).
KeycloakSecurityProcessor now treats an absent iss claim as a
validation failure: when issuer validation is enabled and the introspection result carries no issuer, it throws
CamelAuthorizationException instead of returning early and letting the request through. The earlier code skipped the
comparison whenever the claim was missing, which left the issuer unverified for exactly the tokens that named no
issuer.
Ensure the introspection endpoint returns the iss claim and serves exactly one issuer, so a token from any other
issuer is either named (and rejected) or never introspected as active.
This repository is published for educational and defensive purposes: to help Apache Camel users understand the vulnerability, verify whether they are affected, and confirm that upgrading resolves it. The token introspector is an in-process stub and no real Keycloak server or network call is involved; the "attacker token" is an opaque placeholder string. Do not use this material against systems you do not own or operate.