Summary
An unchecked type assertion in the forEach mutation handler allows any user with permission to create a Policy or ClusterPolicy to crash the cluster-wide background controller into a persistent CrashLoopBackOff. The same bug also causes the admission controller to drop connections and block all matching resource operations. The crash loop persists until the policy is deleted. The vulnerability is confined to the legacy engine — CEL-based policies are unaffected.
Impact
A forEach rule with a patchesJson6902 field that contains a variable substitution resolving to nil at runtime triggers an unrecoverable Go panic in pkg/engine/mutate/mutation.go. When a mutateExisting rule triggers, the admission controller creates an UpdateRequest resource that the background controller processes asynchronously — this resource survives controller restarts, re-triggering the panic on every restart until the policy or UpdateRequest is deleted. The admission controller survives the panic per request (Go's net/http absorbs handler panics) but drops the connection and blocks the matching operation.
Net effect: a single Policy authored by anyone with policies create rights renders the cluster's policy engine unusable until an operator manually intervenes.
Detection
Audit kubectl -n kyverno logs for the panic signature:
panic: interface conversion: interface {} is nil, not string
Look for Policy or ClusterPolicy resources whose forEach rules use patchesJson6902 with variable substitutions referencing fields that may resolve to nil at runtime (e.g., {{ element.nonexistent }}). Pair the audit with a check for unexpected UpdateRequest resources in the kyverno namespace, since those drive the background controller's crash loop.
Mitigation
Upgrade Kyverno to v1.17.2 or v1.16.4 (or later on the matching line). The vulnerable code path was introduced in v1.13.0; releases before that line are unaffected by this specific bug, but other policy-engine concerns apply.
There is no clean workaround on affected versions. As an interim measure, restrict who can create or update Policy and ClusterPolicy resources via RBAC, and prefer CEL-based policies over the legacy engine where possible — CEL policies are not affected.