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
apiCallurlPathwithpath.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
MutatingWebhookConfigurationcluster-wide, intercepts pod creation everywhere, hijacks akube-systempod to inject a sidecar, and patches thesystem:basic-userClusterRole with wildcard permissions. In the second, the tenant createsPolicyExceptionobjects in the protectedkyvernonamespace, 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
apiCallnamespace 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:
urlPathis cleaned without URL-decoding, so validation and the API server read different paths - Attackers can create cluster-wide MutatingWebhookConfigurations or PolicyExceptions in the
kyvernonamespace - 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
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.
Keep reading
Meta's 43M violations: your public claims are evidence
A Santa Fe jury found Facebook committed ~43 million consumer-protection violations by counting public statements times people reached. Version-control your claims.
Read itMemOS npm and PyPI packages shipped a credential stealer
Malicious MemTensor MemOS releases on npm and PyPI drop a Go binary that hunts .npmrc, SSH keys and CI tokens. If an agent framework is in your stack, rotate now.
Read it