Aug 27, 2026·6 min read·2 visits
A missing authorization check in Kyverno's CEL policy compiler allows namespace-scoped users to generate arbitrary resources in other namespaces, leading to cluster privilege escalation.
CVE-2026-54523 is a critical security vulnerability in the Kyverno policy engine (versions 1.18.0 up to 1.18.2) where the CEL generator library fails to validate target namespace boundaries. This allows unprivileged tenants with namespace-scoped policy creation permissions to bypass Kubernetes multi-tenancy limits and execute unauthorized cross-namespace resource creation, potentially escalating privileges to cluster administrator.
Kyverno is a Kubernetes-native policy engine designed to validate, mutate, generate, and clean up Kubernetes resources using declarative policies. To evaluate highly complex configurations and matching criteria, Kyverno integrates the Common Expression Language (CEL) runtime. The vulnerability, designated CVE-2026-54523, stems from a lack of namespace isolation validation within the CEL compilers utilized by Kyverno's namespaced policy types.
Specifically, the flaw resides in the exposure of the generator library to matching and execution contexts within NamespacedMutatingPolicy and NamespacedGeneratingPolicy objects. Under normal operations, a tenant's permissions are restricted to a single namespace, and policies generated by that tenant should not interact with resources outside those boundaries. However, the exposed CEL compiler configurations permitted these namespaced policies to invoke high-privilege cross-namespace actions.
Because the central Kyverno admission controller executes CEL operations utilizing cluster-wide administrative service accounts, it performs these cross-namespace actions on behalf of the namespaced policy without verifying original tenancy constraints. Consequently, a lower-privileged user capable of defining or modifying namespaced policies can leverage this path to deploy unauthorized resources into restricted administrative namespaces like kube-system.
The core defect of CVE-2026-54523 lies in the decoupling of policy tenancy context from the CEL compiler execution context. When compiling NamespacedMutatingPolicy or NamespacedGeneratingPolicy instances, Kyverno initializes the compiler using subpackages located under pkg/cel/policies/gpol/compiler/ and pkg/cel/policies/mpol/compiler/. This initialization registers the generator extension library globally across all policy scopes.
In the vulnerable implementation, the compiler registered the generator library via generator.Lib(generator.Context{ContextInterface: libsctx}, generator.Latest()). This configuration omitted any namespace restriction parameters. As a result, both cluster-wide and namespace-scoped policies were loaded with identical capabilities, allowing namespaced policies to leverage the generator.apply(namespace, resources) function with arbitrary target namespaces.
At runtime, the evaluated CEL payload is passed to the context provider located within pkg/cel/libs/context.go. The function GenerateResources accepted the evaluated namespace argument dynamically without validating if the source policy was permitted to target the specified namespace. Since the background admission controller operates out-of-band with full cluster permissions, the request was processed blindly, breaking the multi-tenant security boundary of the Kubernetes cluster.
The following diagram outlines the vulnerable execution path where an unprivileged namespaced policy leverages the global generator library context to bypass namespace boundaries and create resources inside administrative scopes.
This flow highlights the omission of authorization checks within the compiler registration phase. By registering a global library context without scope limitations, Kyverno allows user-defined variables inside the CEL payload to dictate target namespace destinations.
The remediation for this issue required modifications to both the downstream Kyverno SDK and the Kyverno core codebase. The downstream SDK update (commit 6573937441443e1ba5af9fbb28d5c0f20297f9df) modified Lib() to accept the parent policy namespace, enforcing isolation via a dedicated namespacedImpl structure.
Below is an annotated comparison of the implementation in cel/libs/generator/namespaced_impl.go showing how namespace authorization checks were implemented:
// Patched SDK: cel/libs/generator/namespaced_impl.go
func (c *namespacedImpl) apply_generator_string_list(args ...ref.Val) ref.Val {
if self, err := utils.GetArg[Context](args, 0); err != nil {
return err
} else if namespace, err := utils.GetArg[string](args, 1); err != nil {
return err
} else if namespace != c.namespace {
// Strict comparison prevents cross-namespace target specification
return types.NewErr("cross-namespace generation denied: policy in %q cannot generate into %q", c.namespace, namespace)
}
// Proceed with normal generation if namespaces match
return c.impl.apply_generator_string_list(args...)
}Additionally, in Kyverno Core (commit 5164bcdeda5b57678bc2d7a03ecc2cbb02982dae), the context provider was hardened to prevent namespaced policies from generating cluster-scoped resources, which could otherwise bypass the namespace-isolation checks:
// Patched Kyverno Core: pkg/cel/libs/context.go
if !cp.isNamespacedResource(item.GetAPIVersion(), item.GetKind()) {
// If the target resource is cluster-scoped, ensure the originating policy is not namespace-scoped
if namespace != "" {
return fmt.Errorf("cross-scope generation denied: a policy scoped to namespace %q cannot generate cluster-scoped resource %s/%s", namespace, item.GetAPIVersion(), item.GetKind())
}
targetNamespace = ""
}To execute this attack, an adversary requires Role-Based Access Control (RBAC) permissions to create or update either NamespacedGeneratingPolicy or NamespacedMutatingPolicy resources within at least one namespace. Because these resources are namespaced, platform teams commonly delegate their management to tenant administrators or deployment pipelines within isolated projects.
The attacker creates a malicious NamespacedGeneratingPolicy inside their assigned namespace (e.g., tenant-ns). The policy uses a standard trigger, such as the creation of any ConfigMap in the local namespace. The vulnerability is triggered within the generate field, where the attacker invokes generator.apply() with an external target namespace argument.
An example payload targeting the kube-system namespace is illustrated below:
apiVersion: policies.kyverno.io/v1beta1
kind: NamespacedGeneratingPolicy
metadata:
name: cross-ns-escalate
namespace: tenant-ns
spec:
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["configmaps"]
generate:
- expression: |
generator.apply("kube-system", [
{
"apiVersion": dyn("v1"),
"kind": dyn("ConfigMap"),
"metadata": dyn({
"name": "attacker-controlled-config",
"namespace": "kube-system"
}),
"data": dyn({
"injected-key": "unauthorized-value"
})
}
])When the tenant creates a dummy ConfigMap inside tenant-ns, the background engine executes this policy. Because there are no compiler or execution-time checks to block the "kube-system" parameter in vulnerable versions, Kyverno successfully writes the arbitrary ConfigMap into the administrative namespace.
The security impact of CVE-2026-54523 is categorized as Critical, carrying a CVSS score of 9.6. Although the initial access requirement involves low privileges (RBAC to create policies in a single namespace), the scope metric is classified as Changed (S:C) because the attack breaks the Kubernetes namespace isolation boundary.
By writing resources into restricted namespaces like kube-system, an attacker can escalate privileges to cluster administrator. For instance, the attacker can deploy a new RoleBinding or ClusterRoleBinding within an administrative namespace, linking their own restricted ServiceAccount or User to the high-privileged cluster-admin Role.
Alternatively, an attacker can overwrite existing configurations, inject malicious Sidecar containers into core system deployments, or extract sensitive secrets. Because Kyverno runs with cluster-wide administrative permissions, this vulnerability effectively grants full control of the host Kubernetes cluster to any tenant authorized to manage namespaced policies.
The primary remediation path for CVE-2026-54523 is upgrading Kyverno to version 1.18.2 or later. This release ensures that both core and SDK components are patched, introducing the required namespace validation and preventing cross-scope or cross-namespace resource injection.
In environments where immediate upgrading is not feasible, security administrators must implement strict RBAC restrictions. Specifically, permissions to create, update, or patch NamespacedGeneratingPolicy and NamespacedMutatingPolicy resources should be restricted to trusted cluster administrators and revoked from general application tenants.
Additionally, organizations can deploy runtime detection rules to audit Policy creations. Monitoring Kubernetes API audit logs for policy objects containing the literal pattern generator.apply or generator.Apply can help identify attempted exploitation. If found, these policies should be deleted immediately, and the originating user account should be investigated.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Kyverno Kyverno | >= 1.18.0, < 1.18.2 | 1.18.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862: Missing Authorization |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 | 9.6 (Critical) |
| Exploit Status | PoC available in test suites, no known in-the-wild exploitation |
| KEV Status | Not listed on CISA KEV |
| Impact | Complete cluster-wide privilege escalation and arbitrary write access |
The software does not perform authorization checks when an actor attempts to access or modify a resource.
Prior to version 5.4, the Siemens kas setup utility unconditionally disabled SSH host key verification globally within the invoking user's persistent `~/.ssh/config` file when utilizing SSH keys. This configuration degradation persists after execution, leaving subsequent user SSH connections vulnerable to Man-in-the-Middle (MitM) attacks.
IzPack versions 5.2.6 and earlier are vulnerable to path traversal via UnpackerBase.unpack(). The vulnerability allows unauthenticated attackers to write arbitrary files to the host filesystem during the installation process by crafting malicious installer packages containing directory traversal sequences.
CVE-2026-54511 is a critical security vulnerability in the @logtape/syslog package, which serves as the syslog sink for the LogTape logging library. The flaw is caused by a failure to neutralize C0 control characters in structured data values and to validate keys against RFC 5424 SD-NAME specifications when structured data output is enabled. Remote attackers can leverage this defect to terminate TCP syslog frames and append completely forged syslog records to downstream collectors, compromising the integrity of audit trails and SIEM databases.
A resource leak vulnerability in Wasmtime's WASIp1 native implementation of the fd_renumber system call allows guest WebAssembly applications to leak host file descriptors, ultimately leading to process-wide Denial of Service (DoS) via resource exhaustion.
CVE-2026-55688 is a medium-severity cookie injection vulnerability in the AsyncHttpClient (AHC) library. Due to a failure to validate the domain attribute against the origin server during cookie handling, applications using a shared AHC client instance are vulnerable to cookie-tossing attacks.
A supply-chain compromise affecting the pantheon-agents PyPI package, where versions 0.6.1 and 0.6.2 were uploaded with malicious payloads that exfiltrate sensitive environment variables and credentials.