Vulnerability GHSA-gfjv-gqf2-c888

Medium Risk
MEDIUM RISK
CVSS Score: 5.5
Score Range: 4.0–6.9
Medium severity vulnerabilities (CVSS 4.0–6.9). Important issues that meaningfully reduce security confidence.
9 days ago
September 22, 2026 at 08:40 PM UTC
Gardener: Authorization Bypass via Group Subject Injection
>=1.143.0 <1.143.3, >=1.144.0 <1.144.2
>=1.143.0 <1.143.3, >=1.144.0 <1.144.2

Summary

Gardener: Authorization Bypass via Group Subject Injection

Details

Overview

The manage-members custom verb authorization check in the Gardener API server's customverbauthorizer admission plugin can be bypassed by adding Group or ServiceAccount subjects to a Project's member list. The check is documented as controlling "human users or groups", but the implementation only gates changes to User-kind subjects. A project admin (without manage-members permission) can add arbitrary Group subjects - including system:authenticated - granting all authenticated users full project-level access.

Technical Details

The official Gardener documentation at docs/usage/project/projects.md:90-92 explicitly states: image

However, the mustCheckProjectMembers() function at admission.go compares old and new member lists using findHumanUsersWithRoles(), which only tracks subjects where isHumanUser() returns true:

func mustCheckProjectMembers(oldMembers, members []core.ProjectMember, owner *rbacv1.Subject, userInfo user.Info) bool {
    if apiequality.Semantic.DeepEqual(oldMembers, members) {
        return false
    }
    if userIsOwner(userInfo, owner) {
        return false
    }
    var oldHumanUsers, newHumanUsers = findHumanUsersWithRoles(oldMembers), findHumanUsersWithRoles(members)
    // ...
    return !oldHumanUsers.Equal(newHumanUsers)
}

The isHumanUser() function at admission.go only matches Kind == "User":

func isHumanUser(subject rbacv1.Subject) bool {
    return subject.Kind == rbacv1.UserKind && !strings.HasPrefix(subject.Name, serviceaccount.ServiceAccountUsernamePrefix)
}

Kind: "Group" subjects are NOT matched by isHumanUser(), making Group member changes invisible to the authorization check. A project admin without manage-members permission can freely add or remove Group members.

Steps to reproduce

image

Security Impact

  • Unauthorized access expansion: A project admin can grant project-level access to ANY Kubernetes group, including system:authenticated (all authenticated users) or system:unauthenticated (all unauthenticated users).

Patching & Remediation

  1. Fix isHumanUser() to include Groups: The function should match the documented behavior. Change:
    func isHumanUser(subject rbacv1.Subject) bool {
        return subject.Kind == rbacv1.UserKind && !strings.HasPrefix(subject.Name, serviceaccount.ServiceAccountUsernamePrefix)
    }
    
    To:
    func isNonServiceAccountSubject(subject rbacv1.Subject) bool {
        if subject.Kind == rbacv1.GroupKind {
            return true
        }
        return subject.Kind == rbacv1.UserKind && !strings.HasPrefix(subject.Name, serviceaccount.ServiceAccountUsernamePrefix)
    }
    

Timeline

Published
9 days ago
September 22, 2026 at 08:40 PM UTC
Last Modified
6 hours ago
October 01, 2026 at 08:55 PM UTC