The Keycloak Upgrade Ledger

Every upgrade we have rehearsed, with the environment stated and the clock running.

2026-09-06 · run 2026-09-06-cve-2026-16108-default-groups-disclosure

CVE-2026-16108: realm default-group reads no longer disclose hidden groups

Condition
CVE-2026-16108 (FGAP v2: a realm-viewing admin could see names/ids of hidden default groups via default-groups and the realm representation)

Question

Does 26.7.3 enforce the CVE-2026-16108 fix — i.e. does the default-groups endpoint and the realm representation (defaultGroups field) filter hidden groups by the caller's per-group view permission?

Method

Same FGAP-v2 fixture as 2026-09-06-cve-2026-14613-role-groups-disclosure (realm fgap-cves, service-account delegated admin with view-realm, no per-group view on the hidden group). A group hidden-default-group is added as a realm default group (visible to the master admin, hidden from the delegated admin).

Then, as the delegated admin:

Result

CallResponse
GET .../default-groups200[] (empty; hidden group absent)
GET .../fgap-cves (realm rep)defaultGroups = null (hidden path absent)
GET .../groups/{hidden-default-group}HTTP 403 (control: the group is genuinely hidden)

Finding

26.7.3 filters both default-group read paths by per-group view — the hidden default group appears in neither the default-groups list nor the realm representation's defaultGroups field. The fix adds .filter(auth.groups()::canView) to RealmAdminResource.getDefaultGroups and getRealm, and the equivalent filtering in RealmsAdminResource.toRealmRep (the /admin/realms listing path).

Primary source: commit 073d2e800da18b586e95c4820a06208c60d5ef18 "Realm default-group reads disclose hidden groups under FGAP v2" (closes #51001).

Verification

ClaimPrimary sourceChecked
getDefaultGroups filters by groups()::canViewcommit 073d2e80 diff, RealmAdminResource.java
getRealm filters defaultGroups by groups()::canViewcommit 073d2e80 diff, RealmAdminResource.java
Realm listing (/admin/realms) filters toocommit 073d2e80 diff, RealmsAdminResource.toRealmRep
Hidden default group absent from both live readslive default-groups = [], realm rep defaultGroups = null
Group is genuinely hidden from the callerlive GET /groups/{hidden-default-group} → 403

← Back to the Ledger