High severity7.3NVD Advisory· Published Apr 2, 2026· Updated Apr 16, 2026
CVE-2026-3872
CVE-2026-3872
Description
A flaw was found in Keycloak. This issue allows an attacker, who controls another path on the same web server, to bypass the allowed path in redirect Uniform Resource Identifiers (URIs) that use a wildcard. A successful attack may lead to the theft of an access token, resulting in information disclosure.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.keycloak:keycloak-servicesMaven | < 26.5.7 | 26.5.7 |
Affected products
5cpe:2.3:a:redhat:build_of_keycloak:-:*:*:*:text-only:*:*:*+ 4 more
- cpe:2.3:a:redhat:build_of_keycloak:-:*:*:*:text-only:*:*:*
- cpe:2.3:a:redhat:build_of_keycloak:26.2:*:*:*:text-only:*:*:*
- cpe:2.3:a:redhat:build_of_keycloak:26.2.15:*:*:*:text-only:*:*:*
- cpe:2.3:a:redhat:build_of_keycloak:26.4:*:*:*:text-only:*:*:*
- cpe:2.3:a:redhat:build_of_keycloak:26.4.11:*:*:*:text-only:*:*:*
Patches
135a71b00bc85Consider path params in the unsafe path for RedirectUtils (#436)
2 files changed · +6 −1
services/src/main/java/org/keycloak/protocol/oidc/utils/RedirectUtils.java+1 −1 modified@@ -149,7 +149,7 @@ private static URI toUri(String redirectUri) { // any access to parent folder /../ is unsafe with or without encoding private final static Pattern UNSAFE_PATH_PATTERN = Pattern.compile( - "(/|%2[fF]|%5[cC]|\\\\)(%2[eE]|\\.){2}(/|%2[fF]|%5[cC]|\\\\)|(/|%2[fF]|%5[cC]|\\\\)(%2[eE]|\\.){2}$"); + "(/|%2[fF]|%5[cC]|\\\\)(%2[eE]|\\.){2}(/|%2[fF]|%5[cC]|\\\\|;)|(/|%2[fF]|%5[cC]|\\\\)(%2[eE]|\\.){2}$"); private static boolean areWildcardsAllowed(URI redirectUri) { // wildcars are only allowed if no user-info and no unsafe pattern in path
services/src/test/java/org/keycloak/protocol/oidc/utils/RedirectUtilsTest.java+5 −0 modified@@ -252,15 +252,19 @@ public void testEncodedRedirectUri() { Assert.assertEquals("https://keycloak.org/test/#encode2=a%3Cb", RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/#encode2=a%3Cb", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/../", set, false)); + Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/..;/", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test\\..\\", set, false)); + Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test\\..;param=value\\", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/%2E%2E/", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/%2e%2e/", set, false)); + Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/%2e%2e;param=value\\", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/%2E./", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/%2E.", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test\\%2E.", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test%2f%2E%2e%2F", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test%5C%2E.%5c", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test%5C..", set, false)); + Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test%5C..;/", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/%2F%2E%2E%2Fdocumentation", set, false)); Assert.assertEquals("https://keycloak.org/test/.../", RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/.../", set, false)); Assert.assertEquals("https://keycloak.org/test/%2E../", RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/%2E../", set, false)); // encoded @@ -270,6 +274,7 @@ public void testEncodedRedirectUri() { Assert.assertEquals("https://keycloak.org/test/%252E%252E/#encodeTest=a%3Cb", RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/%252E%252E/#encodeTest=a%3Cb", set, false)); // double-encoded Assert.assertEquals("https://keycloak.org/test/%25252E%25252E/", RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/%25252E%25252E/", set, false)); // triple-encoded Assert.assertEquals("https://keycloak.org/exact/%5C%2F/..", RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/exact/%5C%2F/..", set, false)); + Assert.assertEquals("https://keycloak.org/test/..%3Bsomething/", RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org/test/..%3Bsomething/", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak%2Eorg/test/", set, false)); Assert.assertNull(RedirectUtils.verifyRedirectUri(session, null, "https://keycloak.org%2Ftest%2F%40sample.com", set, false));
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- access.redhat.com/errata/RHSA-2026:6475nvdVendor AdvisoryWEB
- access.redhat.com/errata/RHSA-2026:6476nvdVendor AdvisoryWEB
- access.redhat.com/errata/RHSA-2026:6477nvdVendor AdvisoryWEB
- access.redhat.com/errata/RHSA-2026:6478nvdVendor AdvisoryWEB
- access.redhat.com/security/cve/CVE-2026-3872nvdVendor AdvisoryWEB
- bugzilla.redhat.com/show_bug.cginvdIssue TrackingVendor AdvisoryWEB
- github.com/advisories/GHSA-cjm2-j6cm-6p6mghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-3872ghsaADVISORY
- github.com/keycloak/keycloak/commit/35a71b00bc856ac402711130f60190d3a24795e7ghsaWEB
- github.com/keycloak/keycloak/issues/47718ghsaWEB
News mentions
0No linked articles in our index yet.