
Prueba de concepto ejecutable en Spring Boot y Quarkus que reproduce el bypass de autenticación thread-bound-subject de Apache Camel camel-shiro, con controles afectados y parcheados.
Reproductor de prueba de concepto ejecutable para la vulnerabilidad de Apache Camel en la que el procesador de seguridad Shiro omitía
la verificación de credenciales cuando el Subject de Shiro ya vinculado al hilo actual llevaba el mismo principal que
el exchange entrante. Dado que el hilo que transporta un exchange de Camel se toma de un pool y se reutiliza entre
exchanges, un subject dejado vinculado por un exchange autenticado anterior podía satisfacer la comprobación para un exchange posterior
que presentaba ninguna credencial válida propia — la contraseña de ese exchange posterior nunca se verificaba. El
atacante no necesita más que enviar una petición nombrando un principal que esté actualmente en uso activo.
| Runtime | Directorio | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-shiro 4.22.0 (afectado; corregido en 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-shiro (Camel 4.15.0, afectado; control corregido CQ 3.40.0 / Camel 4.22.1) |
Ambos módulos demuestran el comportamiento afectado y el corregido.
Una ruta está protegida por un ShiroSecurityPolicy construido con alwaysReauthenticate=false — el modo documentado en
el que el subject autenticado se mantiene deliberadamente vinculado al hilo de trabajo (del pool, reutilizado) entre exchanges.
El driver de explotación, dentro de un único hilo de trabajo HTTP, ejecuta dos exchanges en orden:
ringo con la contraseña correcta starr — se autentica y deja el subject de Shiro
vinculado a este hilo (como lo haría una petición autenticada previa en un servicio con carga);ringo pero con una contraseña incorrecta not-starr, en el mismo
hilo.AuthenticationException, aunque el mismo usuario siga vinculado al hilo.# 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
| Propiedad | Valor |
|---|---|
| Componente | camel-shiro (ShiroSecurityProcessor.authenticateUser) |
| CWE | CWE-287 (Autenticación incorrecta) |
| Gravedad | MEDIA |
| Vector de ataque | Una solicitud que nombra a un principal actualmente vinculado a un hilo de trabajo reutilizado, sin portar credenciales válidas propias |
| Impacto | Omisión de autenticación: una solicitud no autenticada es aceptada como un principal ya vinculado; su contraseña nunca se verifica |
| Versiones afectadas | Desde 4.0.0 anterior a 4.18.5, desde 4.19.0 anterior a 4.22.1 |
| Versiones corregidas | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24439 |
| Crédito | Claude Security Scan Tool |
Aviso: https://camel.apache.org/security/CVE-2026-84181.html
ShiroSecurityProcessor.authenticateUser ya no omite el inicio de sesión
cuando el sujeto vinculado al hilo ya porta el mismo principal. El código anterior cortocircuitaba en
currentUser.isAuthenticated() && username.equals(currentUser.getPrincipal()); un nombre de usuario coincidente no dice nada sobre
la contraseña presentada con este intercambio. El procesador ahora llama a currentUser.login(token) en cada intercambio,
de modo que las credenciales presentadas siempre se verifican. alwaysReauthenticate sigue controlando la longevidad de rememberMe
del sujeto, pero ya no condiciona si se verifica la contraseña.
Asegúrese de que el sujeto de Shiro se borre del hilo al final de cada intercambio (para que ningún sujeto pueda ser heredado por
uno posterior) — por ejemplo, con un onCompletion/procesador que llame a ThreadContext.unbindSubject() de Shiro — hasta
que pueda actualizar.
Este repositorio se publica con fines educativos y defensivos: para ayudar a los usuarios de Apache Camel a comprender la vulnerabilidad, verificar si se ven afectados y confirmar que la actualización la resuelve. Los usuarios, contraseñas y claves aquí son elementos locales inertes. No utilice este material contra sistemas que no sean de su propiedad o que no opere.