
Runnable Spring Boot and Quarkus proof-of-concept reproducing the Apache Camel camel-shiro thread-bound-subject authentication bypass, with affected and patched controls.
Runnable proof-of-concept reproducer for the Apache Camel vulnerability where the Shiro security processor skipped
credential verification when the Shiro Subject already bound to the current thread carried the same principal as
the incoming exchange. Because the thread that carries a Camel exchange is drawn from a pool and reused across
exchanges, a subject left bound by an earlier authenticated exchange could satisfy the check for a later exchange
that presented no valid credentials of its own — the password on that later exchange was never verified. The
attacker needs nothing more than to send a request naming a principal that is currently in active use.
| Runtime | Directory | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-shiro 4.22.0 (affected; fixed 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-shiro (Camel 4.15.0, affected; fixed control CQ 3.40.0 / Camel 4.22.1) |
Both modules demonstrate the affected and the fixed behaviour.
A route is protected by a ShiroSecurityPolicy built with alwaysReauthenticate=false — the documented mode in
which the authenticated subject is deliberately kept bound to the (pooled, reused) worker thread between exchanges.
The exploit driver, within one HTTP worker thread, runs two exchanges in order:
ringo with the correct password starr — it authenticates and leaves the Shiro
subject bound to this thread (as a prior authenticated request in a busy service would);ringo but with a wrong password not-starr, on the same
thread.AuthenticationException, even though the same user is still bound to the thread.# Camel Spring Boot
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: wrong password reaches protected logic; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -jar target/cve-2026-84181-shiro-auth-bypass-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: wrong password rejected; >>> 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.15.0): wrong password reaches protected logic
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: wrong password rejected
| Property | Value |
|---|---|
| Component | camel-shiro (ShiroSecurityProcessor.authenticateUser) |
| CWE | CWE-287 (Improper Authentication) |
| Severity | MEDIUM |
| Attack vector | A request naming a principal currently bound to a reused worker thread, carrying no valid credentials of its own |
| Impact | Authentication bypass: an unauthenticated request is accepted as an already-bound principal; its password is never verified |
| Affected Versions | From 4.0.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-24439 |
| Credit | Claude Security Scan Tool |
Advisory: https://camel.apache.org/security/CVE-2026-84181.html
ShiroSecurityProcessor.authenticateUser no longer skips the login
when the thread-bound subject already carries the same principal. The previous code short-circuited on
currentUser.isAuthenticated() && username.equals(currentUser.getPrincipal()); a matching username says nothing about
the password presented with this exchange. The processor now calls currentUser.login(token) on every exchange,
so the presented credentials are always verified. alwaysReauthenticate still controls the rememberMe longevity of
the subject, but it no longer gates whether the password is checked.
Ensure the Shiro subject is cleared from the thread at the end of every exchange (so no subject can be inherited by a
later one) — for example with an onCompletion/processor that calls Shiro's ThreadContext.unbindSubject() — until
you can upgrade.
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 users, passwords and keys here are inert local fixtures. Do not use this material against systems you do not own or operate.