The Kyverno project disclosed CVE-2026-100706 on September 26 — a CVSS 9.9 privilege-escalation vulnerability (GHSA-5qq8-67g6-4h2w) that lets a tenant confined to a single namespace escalate to full cluster administrator. A closely related advisory, CVE-2026-100707 (GHSA-c5qq-7g2q-cpqp, CVSS 7.7), lets the same class of attacker read arbitrary secrets and configmaps across namespaces. Both stem from the same root cause in Kyverno’s apiCall handler and are fixed in version 1.19.1. Any multi-tenant cluster that lets namespace users author their own Policy objects — a common pattern for self-service admission policy — is exploitable today if unpatched.
Kyverno is one of the most widely deployed Kubernetes-native policy engines, running as a cluster-scoped admission webhook with broad RBAC (it needs to mutate, validate, and clone resources across every namespace to do its job). That makes any bug that lets an attacker borrow its ServiceAccount identity a direct path to cluster compromise — this is the fifth apiCall-related advisory against Kyverno in 2026 alone, following CVE-2026-22039, CVE-2026-4789, CVE-2026-84200, and CVE-2026-40868.
The bug
Kyverno’s namespaced Policy resources support an apiCall context entry that lets a policy author’s rule fetch external data — including from the Kubernetes API server itself — during admission decisions. Namespaced policies are supposed to be clamped so their apiCall can only target resources inside the policy’s own namespace, enforced by extracting the namespace from the request’s urlPath.
The clamp is bypassable because validation and execution disagree on how to read that path:
- Validation (
apicall.go) runspath.Clean()on the rawurlPathfor lexical normalization, but never percent-decodes it. A path like/api/v1/namespaces/attacker-ns/%2e%2e/victim-ns/configmaps/namereads as staying insideattacker-nsand passes. - Execution (
executor.go→client.go) hands that same raw path torest.Request.RequestURI(), which callsurl.Parse(). That function does percent-decode%2e%2einto.., collapses the traversal, and the request actually lands invictim-ns— using the Kyverno admission-controller’s own ServiceAccount credentials.
For CVE-2026-100707, this cross-namespace read is enough on its own to leak ConfigMaps, Secrets, and Namespace objects the tenant has no RBAC to see, and error messages from policy validation rules can echo the leaked data back to the attacker.
CVE-2026-100706 takes it further with a POST method apiCall. Because the Kyverno controller ServiceAccount has create on MutatingWebhookConfiguration (a cluster-scoped resource), the same encoded-traversal trick lets a tenant register a cluster-wide mutating webhook with no namespace restriction — one that intercepts pod creation everywhere, including kube-system. The attacker then triggers their own webhook to inject a sidecar that patches a built-in ClusterRole (e.g., system:basic-user) to grant cluster-admin, or alternatively drops a PolicyException into the kyverno namespace to blanket-disable enforcing policies. Either path ends with a namespace tenant holding cluster-admin.
Who’s affected
- Kyverno versions before 1.19.1, running as a cluster admission controller
- Highest risk: multi-tenant clusters (platform teams, internal PaaS, managed Kubernetes offerings) that grant tenants
createon namespacedkyverno.io/v1.Policyobjects for self-service policy authoring — a pattern Kyverno explicitly markets as safe because policies are “namespace-scoped” - The precondition is low: only
createon namespacedPolicyplus baseline workload-creation permissions (roughly aneditClusterRole) in one namespace
CVSS vectors: CVE-2026-100706 is AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H (9.9); CVE-2026-100707 is AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N (7.7). Both require only network access and low privileges, no user interaction, and Scope: Changed — the classic confused-deputy signature of an admission controller acting on an attacker’s behalf.
Mitigation
- Upgrade to Kyverno 1.19.1 immediately on any cluster where non-admin users can create
Policyresources. This is the only complete fix — the advisory notespath.Clean()alone can’t defend against%2e%2e,..%2f,.%2e/, or%2e%2e%2fvariants without decoding first. - Until patched, restrict
create/updateonpolicies.kyverno.ioto trusted, cluster-admin-equivalent identities only — treat namespacedPolicyauthorship as cluster-admin-equivalent, because it now effectively is. - Audit for existing
MutatingWebhookConfigurationobjects andPolicyExceptionresources in thekyvernonamespace that weren’t created by your platform team; either is a plausible sign of prior exploitation. - Review the Kyverno controller ServiceAccount’s RBAC — reducing its cluster-wide
creategrants onMutatingWebhookConfigurationandPolicyExceptionwhere feasible removes the second half of the attack chain even if a similar path-handling bug resurfaces. - Advisories: GHSA-5qq8-67g6-4h2w (CVE-2026-100706) and GHSA-c5qq-7g2q-cpqp (CVE-2026-100707), both crediting researcher Artem Cherezov.
Given the pattern of repeated apiCall-related credential and boundary bypasses in Kyverno this year, clusters relying on it as a trust boundary between tenants should treat any apiCall-capable policy grant as a standing privilege-escalation risk, not just a per-CVE patching exercise.