Bug 2499592 (CVE-2026-15572)

Summary: CVE-2026-15572 keycloak-services: keycloak-services: DCR protocol mapper type-swap policy bypass allows privilege escalation
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security DevOps Team <prodsec-dev>
Status: NEW --- QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: aschwart, aszczucz, boliveir, drichtar, mposolda, pjindal, rmartinc, security-response-team, ssilvert, sthorger, vmuzikar
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in Keycloak's Dynamic Client Registration (DCR) security policy management. The "Allowed Protocol Mapper Types" policy, which restricts which types of data mappers a client can use, fails to re-validate the mapper type during a client update if the mapper's configuration remains unchanged. An attacker with client registration privileges can exploit this by first registering an allowed mapper type with a malicious configuration and then swapping it for a restricted, high-privilege mapper type (such as one that hardcodes administrative roles). This allows the attacker to gain full administrative access to the Keycloak realm.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Deadline: 2026-10-04   

Description OSIDB Bzimport 2026-07-13 07:37:16 UTC
A policy bypass vulnerability exists in Keycloak's Dynamic Client Registration (DCR) "Allowed Protocol Mapper Types" policy. The root cause is located in the testMappers() method of ProtocolMappersClientRegistrationPolicy.java.
When a client is updated, the policy checks if the protocol mapper type is in the allow-list. If it is not, the code attempts to verify if the mapper already exists. However, it only validates that the config map of the incoming mapper matches the config of the existing persisted mapper; it fails to verify that the protocolMapper type itself has not changed.
An attacker can exploit this by:
Registering a client with an allowed mapper type (e.g., oidc-usermodel-attribute-mapper) but providing a configuration intended for a restricted mapper (e.g., {"role": "realm-management.realm-admin"}).

Performing a DCR PUT update that keeps the configuration identical but changes the protocolMapper type to a disallowed one, such as oidc-hardcoded-role-mapper.


Because the configuration is identical, the policy bypasses the type check. Once persisted, the oidc-hardcoded-role-mapper uses the "role" configuration to inject the realm-admin role into the client's tokens, escalating the attacker to a full realm administrator.