Summary
A user who can create a namespaced CleanupPolicy can cause Kyverno to execute attacker-controlled Kubernetes API requests with the cleanup-controller service account. The cleanup controller does not pass the policy namespace to the shared context loader, which disables an existing restriction that requires API paths used by namespaced policies to remain in the policy namespace. On a default Kyverno installation, this primitive can be chained through GlobalContextEntry processing to install a MutatingWebhookConfiguration that injects privileged containers into Pods admitted in other namespaces, resulting in full cluster takeover.
Impact
The root cause is in pkg/controllers/cleanup/controller.go, where the cleanup controller invokes the context-loader factory with a nil policy argument. DefaultContextLoaderFactory initializes policyNamespace to an empty string and only populates it when it receives a non-nil namespaced policy. The API-call implementation in pkg/engine/apicall/apiCall.go contains the intended namespace restriction but runs it only when policyNamespace is non-empty — so with nil passed, all namespace checks are skipped and the attacker-selected path, method, and request body are sent with the cleanup-controller's service account via the raw API client. By chaining this through GlobalContextEntry processing — where the cleanup-controller can create a cluster-scoped GlobalContextEntry that Kyverno's admission-controller then executes with admission-controller credentials — an attacker can install a MutatingWebhookConfiguration. The upstream proof of concept demonstrates injecting a privileged init container that mounts the KinD control-plane /etc/kubernetes directory, reads admin.conf, and grants the attacker's tenant service account cluster-admin.
Detection
Monitor Kubernetes API server audit logs for unexpected MutatingWebhookConfiguration create or update events originating from the Kyverno cleanup-controller or admission-controller service accounts. Alert on CleanupPolicy objects that reference apiCall entries with unusual or cluster-scoped URL paths. Review GlobalContextEntry creations for payloads that could redirect the admission-controller's apiCall. Consult the advisory at the reference URL for the full proof-of-concept chain.
Mitigation
Upgrade Kyverno to version 1.19.2 or later, which fixes the cleanup controller to pass the correct policy namespace to the context loader, re-enabling the existing namespace restriction for apiCall paths in CleanupPolicy. Until upgraded, restrict CleanupPolicy creation permissions to highly trusted identities only, removing the create verb from any tenant-facing ClusterRole or Role that targets kyverno.io cleanuppolicies resources. Do not grant untrusted tenants access to the GlobalContextEntry resource.
Related Security Guidance
References
- GHSA-rcxg-3f92-3mgr — Kyverno Security Advisory