CVE-2026-14613: role→groups endpoint filters hidden groups under FGAP v2
- Condition
- CVE-2026-14613 (FGAP v2: an admin who can see a role can read all groups assigned to it — the per-group view check was missing)
Question
Does 26.7.3 enforce the CVE-2026-14613 fix — i.e. does
GET /admin/realms/{realm}/roles/{role}/groups (and the client-role variant)
now filter the returned groups by the caller's per-group view permission,
instead of returning every group that has the role?
Method
Built the FGAP-v2 "delegated admin" fixture in a fresh realm
(adminPermissionsEnabled=true) and exercised the endpoint as that admin. The
delegated admin is a service-account (client-credentials) subject, not a
password user: ROPC against a hand-rolled realm hits the undiagnosed
"Account is not fully set up" quirk we have hit repeatedly in this lab, and a
service-account token evaluates FGAP v2 identically.
Fixture (reproducible via bin/fgap-rbac-cves.sh):
- Realm
fgap-cves,adminPermissionsEnabled=true. - Client
fgap-delegate(confidential, service account); its service-account user is the delegated admin. - Grant the service-account user
view-realm+query-groups(realm-management client roles) —view-realmto reach realm-level role endpoints,query-groupssogetGroupsInRole'srequireList()gate passes and the per-group filter is what is actually exercised. - Realm role
visible-realm-role; groupsvisible-groupandhidden-group; the role mapped to both groups. - FGAP permission: a
userpolicy on theadmin-permissionsclient referencing the service-account user, and ascopepermission grantingviewonvisible-grouponly (resource typeGroups, resource = visible-group id).
Then, as the delegated admin:
GET /admin/realms/fgap-cves/groups/{hidden-group}→ expect 403GET /admin/realms/fgap-cves/groups/{visible-group}→ expect 200GET /admin/realms/fgap-cves/roles/visible-realm-role/groups→ expect onlyvisible-group, nothidden-group
Result
| Call | Response |
|---|---|
GET .../groups/{hidden-group} | HTTP 403 |
GET .../groups/{visible-group} | HTTP 200 |
GET .../roles/visible-realm-role/groups | 200 — [{"name":"visible-group",...}] only; hidden-group absent |
Finding
26.7.3 filters the role→groups result by per-group view — the caller sees
visible-group and not hidden-group. The fix is two-part and both are present:
RoleContainerResource.getGroupsInRolenow callsauth.groups().requireList()(a caller with no group-list permission is rejected outright);JpaRealmProvider.getGroupsByRoleStreamnow appliesAdminPermissionsSchema.SCHEMA.applyAuthorizationFilters(GROUPS, …), so the groups returned are limited to those the caller may view.
Primary source: commit dc0f68bd235d816fc2e7a3e690a3c6fd237ec7b1
"Fine-Grained Admin Permissions Bypass via Role Groups Endpoint" (closes #50616).
Verification
| Claim | Primary source | Checked |
|---|---|---|
Fix adds requireList() to getGroupsInRole | commit dc0f68bd diff, RoleContainerResource.java | ☑ |
Fix filters getGroupsByRoleStream by group authorization | commit dc0f68bd diff, JpaRealmProvider.java (applyAuthorizationFilters(GROUPS)) | ☑ |
| Hidden group excluded, visible group returned | live GET /roles/visible-realm-role/groups response quoted above | ☑ |
| Direct read of hidden group is already 403 (per-group view) | live GET /groups/{hidden-group} → 403 | ☑ |