Sep 23, 2026·7 min read·4 visits
Gardener's admission plugin failed to compare Group and ServiceAccount subjects during membership updates, enabling restricted project administrators to bypass permission checks and escalate access by injecting arbitrary groups.
An incorrect authorization vulnerability (CWE-863) in Gardener's customverbauthorizer admission plugin allows project administrators lacking the manage-members permission to inject arbitrary Group or ServiceAccount subjects, granting unauthorized access to project resources.
Gardener is an open-source system designed to orchestrate the management of Kubernetes clusters across multiple cloud providers. The Gardener API Server implements custom resource definitions (CRDs), including the Project resource, to partition clusters, users, and resources into administrative boundaries. To enforce access controls on these project boundaries, Gardener utilizes a dedicated admission plugin named customverbauthorizer.
The role of the customverbauthorizer admission plugin is to validate operations against custom RBAC verbs. Specifically, modifying the membership of a project (defined under Project.spec.members) is a highly sensitive action that normally requires the initiator to possess the manage-members custom verb authorization. This check ensures that a standard project administrator cannot arbitrarily elevate the privileges of other entities or introduce unauthorized external users into the project scope.
The vulnerability, identified as CVE-2026-79767 (and GHSA-gfjv-gqf2-c888), resides in the logic that determines if a membership modification has occurred. Due to an incomplete filtering mechanism within the validation code, changes involving Group and ServiceAccount subjects were completely omitted from comparison checks. This allows a project administrator who lacks the manage-members permission to execute update operations that inject unauthorized groups or service accounts directly into the project configuration.
The root cause of this vulnerability lies in the implementation of the helper function mustCheckProjectMembers inside the customverbauthorizer admission plugin. When an update request for a Project resource is processed, this function is called to determine if the membership list (Project.spec.members) has been modified in a way that necessitates the custom verb authorization check. The function compares the previous state of the members array against the newly requested state.
To perform this comparison, the plugin utilized a helper function named findHumanUsersWithRoles. This function was designed to extract and track only human user subjects from the members list, using the following logic to identify them:
func isHumanUser(subject rbacv1.Subject) bool {
return subject.Kind == rbacv1.UserKind && !strings.HasPrefix(subject.Name, serviceaccount.ServiceAccountUsernamePrefix)
}Because the comparison logic specifically queried for rbacv1.UserKind and excluded service account prefixes, any Subject of kind Group or ServiceAccount was silently ignored during the member extraction. Consequently, if an attacker updated a project to append a new Group subject (for example, the default system:authenticated group) or an external ServiceAccount subject, the comparison sets returned by findHumanUsersWithRoles for both the old and new specifications remained identical. The mustCheckProjectMembers function returned false, indicating that no restricted membership changes had occurred, and the API server processed the request without enforcing the manage-members authorization check.
A detailed review of the patch commit reveals how the vulnerability was introduced and remediated. The legacy code was based on an allowlist approach that strictly extracted human users, leaving all other subject types unmonitored. This logical gap meant that any non-human subject could be manipulated by unauthorized administrators.
// Legacy Vulnerable Implementation
func findHumanUsersWithRoles(members []core.ProjectMember) sets.Set[humanMembership] {
result := sets.New[humanMembership]()
for _, member := range members {
if isHumanUser(member.Subject) {
memberKey := humanMemberKey(member.Subject)
for _, role := range member.Roles {
result.Insert(humanMembership{member: memberKey, role: role})
}
}
}
return result
}The patched implementation reverses this paradigm. It shifts from an allowlist of human users to a blocklist of local service accounts. The new helper function findNonServiceAccountsWithRoles extracts all subjects except those explicitly identified as local service accounts. This ensures that any modification to Group or external User subjects is caught during the evaluation.
// Patched Implementation
func findNonServiceAccountsWithRoles(members []core.ProjectMember) sets.Set[membership] {
result := sets.New[membership]()
for _, member := range members {
if !isServiceAccountSubject(member.Subject) {
memberKey := memberSubjectKey(member.Subject)
for _, role := range member.Roles {
result.Insert(membership{member: memberKey, role: role})
}
}
}
return result
}The helper isServiceAccountSubject was also carefully designed to ensure service account groups (e.g., system:serviceaccounts) are not treated as local service accounts, preventing project admins from managing service account groups without authorization.
To exploit this vulnerability, an attacker must have administrative control over a Gardener project but must lack the manage-members custom verb permission. The attack is executed by directly modifying the spec.members section of the Project resource via the Kubernetes API.
In a standard scenario, the attacker identifies a target project where they are registered as a limited administrator. The existing members list contains only authorized human operators:
apiVersion: core.gardener.cloud/v1alpha1
kind: Project
metadata:
name: target-project
spec:
owner:
apiGroup: rbac.authorization.k8s.io
kind: User
name: owner@example.com
members:
- roles:
- admin
subject:
apiGroup: rbac.authorization.k8s.io
kind: User
name: restricted-admin@example.comThe attacker submits an HTTP PUT or PATCH request to update the project resource. They inject a new entry into the members array containing a broad Kubernetes group, such as the standard system:authenticated group, assigning it the admin role:
members:
- roles:
- admin
subject:
apiGroup: rbac.authorization.k8s.io
kind: User
name: restricted-admin@example.com
- roles:
- admin
subject:
apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:authenticatedBecause the customverbauthorizer processes only human users, it compares the before-and-after user sets, finds them identical (both only containing restricted-admin@example.com), and permits the transaction. Once committed, any authenticated user in the cluster inherits project administrator capabilities, bypassing the intended RBAC boundaries.
The security impact of CVE-2026-79767 is classified as Medium with a CVSS v3.1 base score of 5.5. The vulnerability requires high privileges (PR:H) because the attacker must already possess an administrative role within the targeted project to modify the resource. However, the integrity impact is high (I:H) within the scope of the affected project.
Successful exploitation allows complete authorization bypass within the project boundary. By mapping the project's administrator role to generic groups (like system:authenticated) or external service accounts, an attacker can expose all resources managed within the project. This includes access to Shoots (the managed Kubernetes clusters), sensitive Kubernetes Secrets containing credentials, and cloud provider infrastructure integration tokens (e.g., AWS, Azure, GCP access keys).
This logical bypass weakens the multi-tenancy assurances provided by Gardener. Although it does not escape the boundary of the master Kubernetes API server, the compromise of project isolation allows lateral movement across any target clusters managed under the compromised project scope.
The primary remediation step is to upgrade the Gardener deployment to a non-vulnerable release. Security teams should target the respective patch branches depending on their current deployment path:
To audit existing Gardener environments for active exploitation or misconfigurations, administrators can execute a script to identify any projects that contain non-human subjects in their members list. The following Bash script utilizes kubectl and jq to parse project resources:
#!/usr/bin/env bash
set -euo pipefail
echo "[*] Auditing Gardener Project resources for non-User subjects..."
PROJECTS_JSON=$(kubectl get projects -o json)
echo "$PROJECTS_JSON" | jq -r '
.items[] | {
name: .metadata.name,
suspicious_members: [
.spec.members[]? | select(.subject.kind != "User") | {
kind: .subject.kind,
name: .subject.name,
roles: .roles
}
]
} | select(.suspicious_members | length > 0)
'Additionally, security operations teams should analyze Kubernetes API server audit logs for update requests to the projects API endpoint. Audit entries where the user executing the change does not possess the manage-members custom verb, but the payload contains Group or ServiceAccount additions, indicate potential exploitation attempts.
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Gardener gardener | < 1.142.6 | 1.142.6 |
Gardener gardener | >= 1.143.0, < 1.143.3 | 1.143.3 |
Gardener gardener | >= 1.144.0, < 1.144.2 | 1.144.2 |
Gardener gardener | < 1.145.0 | 1.145.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-863 (Incorrect Authorization) |
| Attack Vector | Network (AV:N) |
| CVSS Score | 5.5 (Medium Severity) |
| EPSS Score | N/A |
| Impact | Privilege Escalation / Authorization Bypass |
| Exploit Status | None (No public exploits or active exploitation reported) |
| KEV Status | Not Listed in CISA KEV |
The software performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly prove that the actor is authorized to perform the action.
Cloudreve before version 4.18.0 contains a Time-of-Check to Time-of-Use (TOCTOU) race condition in its storage-quota verification logic. Authenticated attackers with basic write access can trigger multiple parallel upload sessions to bypass their storage limits, leading to host disk space exhaustion and Denial of Service.
CVE-2026-77637 is a privilege scope bypass vulnerability in Cloudreve. It allows authenticated clients possessing read-only administrative credentials to access sensitive administrative tool endpoints that should require write-level permissions.
Cloudreve versions prior to 4.18.0 contain a Server-Side Request Forgery (SSRF) vulnerability. The application's validation logic fails to canonicalize various IPv4-in-IPv6 transition formats, such as NAT64, 6to4, and Teredo addresses. Consequently, an authenticated user with remote-download permissions can issue requests that bypass SSRF network boundaries, enabling connection routing to loopback, private, or cloud metadata endpoints.
Hatchet V1 Dispatcher before version 0.95.3 fails to enforce proper tenant boundaries when managing active stream connections for durable task completions. Because the global lookup map is keyed solely by task external identifiers, authenticated attackers who obtain a victim's task UUID can register a stream subscription and receive task results belonging to another tenant.
CVE-2026-88978 is a critical cross-tenant data exposure vulnerability in Hatchet, a platform for orchestrating background tasks and durable workflows. The flaw exists in the durable-task event retrieval system where client-supplied task, node, and branch UUIDs are resolved via the ListSatisfiedEntries database query without verifying the tenant ownership of the requesting worker context.
An unauthenticated timing oracle vulnerability exists in Traefik's BasicAuth middleware from version 3.6.11 up to (but not including) 3.7.13. By utilizing a request coalescing mechanism (singleflight.Group) that relies on server-side stored secret hashes for key generation, the software introduces a timing discrepancy. Concurrent requests targeting non-existent usernames generate identical singleflight keys and coalesce, resulting in accelerated response times. Conversely, requests targeting valid usernames produce distinct keys and execute independently, allowing remote attackers to systematically enumerate valid usernames.