[CVE-2026-16105] Missing per-role authorization on RoleContainerResou… - #51084
[CVE-2026-16105] Missing per-role authorization on RoleContainerResou…#51084martin-kanis wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds per-role authorization to name-based composite role endpoints, addressing CVE-2026-16105.
Changes:
- Requires manage permission on the target role when adding or deleting composites.
- Adds integration tests confirming unauthorized operations return forbidden without modifying composites.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java |
Enforces target-role manage authorization. |
tests/base/src/test/java/org/keycloak/tests/admin/authz/rbac/InternalClientManagementTest.java |
Covers unauthorized composite additions and removals. |
|
Hi @martin-kanis! The fix looks good overall, I just noticed something that might be worth handling now or at least as a follow up. The same container-only auth pattern also exists on the GET side. The name-based read endpoints in Their ID-based equivalents in |
|
Thanks for the PR. Before we proceed, I want to share some analysis of what this change actually does under both RBAC and FGAP evaluation, because I think we need to align on whether this addresses a real security boundary. No
|
|
@vramik do you think this should have not been assigned a CVE? |
…rce composite endpoints Closes keycloak#51002 Signed-off-by: Martin Kanis <mkanis@ibm.com> # Conflicts: # services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
tests/base/src/test/java/org/keycloak/tests/admin/authz/rbac/InternalClientManagementTest.java:136
composites.iterator().next()will throwNoSuchElementExceptionif theadminrole has no composites in a given environment/configuration, causing a test failure unrelated to the authorization behavior. Consider asserting the set is non-empty (with a clear failure message), or making the test self-contained by creating a temporary role and ensuring it is added as a composite (viaadminClient) before attempting the forbidden delete.
Set<RoleRepresentation> composites = client.realm(masterRealm.getName()).roles()
.get(AdminRoles.ADMIN).getRoleComposites();
int compositesBefore = composites.size();
RoleRepresentation targetComposite = composites.iterator().next();
tests/base/src/test/java/org/keycloak/tests/admin/authz/rbac/InternalClientManagementTest.java:156
- The test creates
TEMP_ROLE_NAMEbut does not delete it. If the test fails mid-flight or the suite is rerun against a shared/dirty realm, this can cause interference (e.g., role already exists) and make the suite flaky. Add a cleanup step (preferably in afinallyblock insiderunAs) to delete the temp role even when assertions fail.
adminClient.realm(masterRealm.getName()).roles().create(
new RoleRepresentation(TEMP_ROLE_NAME, "temp", false));
RoleRepresentation tempRole = adminClient.realm(masterRealm.getName()).roles()
.get(TEMP_ROLE_NAME).toRepresentation();
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
tests/base/src/test/java/org/keycloak/tests/admin/authz/rbac/InternalClientManagementTest.java:136
composites.iterator().next()will throwNoSuchElementExceptionif theadminrole has no composites in a given environment/config. To make the test robust, explicitly create/attach a known composite (viaadminClient) before selecting it, or assert the set is non-empty with a clear failure message before callingnext().
RoleRepresentation targetComposite = composites.iterator().next();
tests/base/src/test/java/org/keycloak/tests/admin/authz/rbac/InternalClientManagementTest.java:156
- This test creates a realm role but doesn’t clean it up, which can cause cross-test pollution and intermittent failures when tests are re-run against the same realm. Consider deleting
TEMP_ROLE_NAMEin afinallyblock (or using existing test utilities/hooks for cleanup), and/or pre-deleting if it already exists before creation.
adminClient.realm(masterRealm.getName()).roles().create(
new RoleRepresentation(TEMP_ROLE_NAME, "temp", false));
RoleRepresentation tempRole = adminClient.realm(masterRealm.getName()).roles()
.get(TEMP_ROLE_NAME).toRepresentation();
…rce composite endpoints
Closes #51002