Skip to content
Rush Commerce
Software & Dev4 min read

Kyverno CVE-2026-100706: validate the string you send

Kyverno CVE-2026-100706 lets a namespace tenant become cluster admin because validation cleaned one path and the API server received another. Patch to 1.19.1.

Kyverno CVE-2026-100706 is the second time in nine months that the same feature has handed cluster admin to a namespace tenant, and the second time the root cause is a mismatch between the string that got validated and the string that got sent. If you run Kubernetes admission policies, patch to 1.19.1 and then go read your own input validation, because this bug class is not specific to Kyverno.

What actually happened

Per the Kyverno security advisory and the NVD record:

  • Affected: Kyverno before 1.19.1. CVSS 3.1 base score 9.9, CVSS 4.0 9.4, classified as CWE-441. The advisory published September 10; the CVE record landed in NVD on September 26.
  • The mechanism is a decode gap. Kyverno validates a policy's apiCall urlPath with path.Clean() without URL-decoding it first, and extracts the namespace from that cleaned string. The raw path — still carrying %2e%2e — is what gets sent to the API server, where client-go decodes it. Validation and execution disagree about what the path says.
  • Privileges required are low. A namespace tenant who can create policies in their own namespace is enough. The request then runs as the admission-controller ServiceAccount, which has broad cluster RBAC.
  • Two documented paths to cluster admin. In the first, the tenant creates a MutatingWebhookConfiguration cluster-wide, intercepts pod creation everywhere, hijacks a kube-system pod to inject a sidecar, and patches the system:basic-user ClusterRole with wildcard permissions. In the second, the tenant creates PolicyException objects in the protected kyverno namespace, switches off the enforcing policies covering their own namespace, and runs the privileged workloads those policies existed to block.
  • No workarounds. The advisory documents none. CISA's SSVC assessment records no observed exploitation, not automatable, technical impact total.
  • It supersedes January's fix. GHSA-8p9x-46gm-qfx2 (CVE-2026-22039) closed the same apiCall namespace escape. Percent-encoding walked around the patch.

Why this bug class matters for your business

Canonicalize once, then use the canonical value — never the original. That is the whole lesson. Kyverno cleaned the path, read the namespace out of the clean version, and then forwarded the dirty version. Every layer in that chain was reasonable in isolation. The bug lives in the gap. This is exactly the shape of the PeopleSoft WAF bypass we covered this week, where ShinyHunters beat WAF rules with a single %50: a check that reads one spelling and a consumer that accepts many.

Grep your own code for it today. Anywhere you validate a path, hostname, filename, S3 key, or redirect target and then pass along the untouched input, you have the same defect waiting. The fix is structural: decode and normalize as the first operation, validate the normalized form, and forward only the normalized form. If the normalized string is not what you send, your validation is decoration.

Your admission controller is the most privileged workload in the cluster. It holds RBAC to mutate anything, so any authorization flaw in it is a full compromise rather than a scoped one. Treat it like a secrets manager, not like a linter: pin its version, subscribe to its advisories, and patch it on the same urgency tier as your control plane. A policy engine that fails open is bad. One that escalates is worse.

Multi-tenancy by namespace is thinner than it looks. Namespaces are a naming boundary that RBAC makes load-bearing. Anything cluster-scoped — webhook configurations, CRDs, ClusterRoles — sits outside that boundary. If you let tenants author policy objects, you are letting them supply input to a privileged component. Assume that input is hostile and check what else a tenant can reach if the check fails.

Fixes for path-handling bugs deserve a second look. January's patch was correct against the reported spelling and wrong against the next one. When you fix an encoding or traversal bug, the review question is not "does the reported payload fail now" but "what else decodes to this." Double encoding, mixed case, alternate separators, and Unicode normalization are all in the same family.

Key takeaways

  • CVE-2026-100706 affects Kyverno before 1.19.1 — CVSS 9.9, privilege escalation from namespace tenant to cluster admin, no workaround
  • Cause: urlPath is cleaned without URL-decoding, so validation and the API server read different paths
  • Attackers can create cluster-wide MutatingWebhookConfigurations or PolicyExceptions in the kyverno namespace
  • It bypasses January's fix for the same feature (CVE-2026-22039) using percent-encoded traversal
  • Operator move: patch to 1.19.1, then audit your own code for validate-one-string-send-another
  • Decode and normalize first, validate the normalized value, and forward only the normalized value

The bug was not in the policy engine's logic — it was in the order of two lines. We build and review systems where input is normalized once at the edge and every downstream check reads the same bytes. See how we build, or have us audit your validation paths.

Sources: Kyverno security advisory GHSA-5qq8-67g6-4h2w, NVD CVE-2026-100706.

  • #security
  • #kyverno
  • #kubernetes
  • #cve-2026-100706
  • #admission-control
TR

Tommy Rush — Founder, Rush Commerce

Operator turned builder. 15+ years running operations — now shipping the systems businesses run on. More

Get The Rush Report weekly — one email, zero fluff.