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) runs path.Clean() on the raw urlPath for lexical normalization, but never percent-decodes it. A path like /api/v1/namespaces/attacker-ns/%2e%2e/victim-ns/configmaps/name reads as staying inside attacker-ns and passes.
  • Execution (executor.go → client.go) hands that same raw path to rest.Request.RequestURI(), which calls url.Parse(). That function does percent-decode %2e%2e into .., collapses the traversal, and the request actually lands in victim-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 create on namespaced kyverno.io/v1.Policy objects for self-service policy authoring — a pattern Kyverno explicitly markets as safe because policies are “namespace-scoped”
  • The precondition is low: only create on namespaced Policy plus baseline workload-creation permissions (roughly an edit ClusterRole) 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 Policy resources. This is the only complete fix — the advisory notes path.Clean() alone can’t defend against %2e%2e, ..%2f, .%2e/, or %2e%2e%2f variants without decoding first.
  • Until patched, restrict create/update on policies.kyverno.io to trusted, cluster-admin-equivalent identities only — treat namespaced Policy authorship as cluster-admin-equivalent, because it now effectively is.
  • Audit for existing MutatingWebhookConfiguration objects and PolicyException resources in the kyverno namespace 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 create grants on MutatingWebhookConfiguration and PolicyException where 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.