CVE-2026-16105: name-based composite endpoints now enforce per-role authorization
- Condition
- CVE-2026-16105 (a delegated manage-realm admin could add/remove child roles from built-in admin roles via the name-based composite endpoint
Question
Does 26.7.3 enforce the CVE-2026-16105 fix — i.e. do the name-based
composite endpoints (/roles/{role-name}/composites and
/clients/{client-uuid}/roles/{role-name}/composites) now call
auth.roles().requireManage(role) like the id-based
(/roles-by-id/{role-id}/composites) endpoints always did?
Method
Same FGAP-v2 fixture realm (fgap-cves), but the delegated admin is granted
manage-realm (realm-management client role) instead of remaining a
view-only admin — this is the "delegated administrator with manage-realm
permissions" the advisory names.
Target: the realm-management client's realm-admin composite role (a built-in
admin role — the class the CVE is about). Pick one of its child roles and attempt
to remove it through the name-based endpoint.
Then, as the delegated admin:
DELETE /admin/realms/fgap-cves/clients/{realm-management}/roles/realm-admin/compositeswith[{"id": <child-id>}]→ expect 403 (fix present; pre-fix it succeeded)
Result
| Call | Response |
|---|---|
DELETE .../roles/realm-admin/composites (name-based) | HTTP 403 |
child role still a composite of realm-admin (read back as master admin) | True — unchanged |
Target child in this run: manage-organizations (first composite returned; the
choice is immaterial — the guard is per-role, not per-child).
Finding
26.7.3 rejects the composite edit with 403 and leaves the role unchanged.
The fix adds auth.roles().requireManage(role) to both addComposites and
deleteComposites in RoleContainerResource (the name-based path). The id-based
RoleByIdResource path already had this check — the vulnerability was that the
two paths had drifted.
Primary source: commit 81ada68d956b3b412741c5c8e9dbefacc3410cf9
"Missing per-role authorization on RoleContainerResource composite endpoints"
(closes #51002).
Verification
| Claim | Primary source | Checked |
|---|---|---|
addComposites gains requireManage(role) | commit 81ada68d diff, RoleContainerResource.java | ☑ |
deleteComposites gains requireManage(role) | commit 81ada68d diff, RoleContainerResource.java | ☑ |
| Id-based path already guarded (drift, not absence) | RoleByIdResource.java addComposites/deleteComposites call requireManage | ☑ |
| Name-based delete now rejected for delegated admin | live DELETE .../roles/realm-admin/composites → 403 | ☑ |
| Composite unchanged after the attempt | live read-back: child still present | ☑ |