Introduction
A flaw in Kyverno's apiCall feature silently forwards the admission controller's privileged ServiceAccount token to any URL specified in a ClusterPolicy, with no destination validation whatsoever. For organizations running Kyverno in production Kubernetes clusters, this means anyone with ClusterPolicy write access can exfiltrate a token capable of patching webhook configurations and achieving full cluster takeover.
Kyverno is a Kubernetes native policy engine designed for cloud native platform engineering teams, enabling policy as code for cluster governance, security enforcement, and automated resource management. It is a CNCF incubating project with broad adoption across enterprise Kubernetes deployments. Its role as an admission controller places it directly in the critical path of every API request to the cluster, making vulnerabilities in Kyverno particularly consequential.
Technical Information
CVE-2026-41323 arises from two distinct implementation issues in Kyverno's apiCall feature that, when combined, form a complete credential theft and cluster compromise chain.
Root Cause: Unvalidated URL and Implicit Token Injection
The first issue is the absence of any validation on the service URL specified in a ClusterPolicy's apiCall block. The URL is passed directly into the HTTP request creation process with no scheme checking, no IP restriction, and no allowlist enforcement. This satisfies the conditions for CWE-918 (Server Side Request Forgery): the application constructs a request to a user controlled URL without sanitization.
The second issue is implicit credential injection. When the outgoing HTTP request does not already contain an Authorization header, the Kyverno executor automatically reads its own ServiceAccount token from the pod's filesystem and injects it as a Bearer token. This is classified under CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor).
The token that gets injected belongs to the Kyverno admission controller's ServiceAccount. In a default Helm installation, this ServiceAccount holds the following verified permissions:
| Action | Result |
|---|---|
| List pods in all namespaces | Allowed |
| Read configmaps in kube-system | Allowed |
| Patch MutatingWebhookConfiguration | Allowed |
| Patch ValidatingWebhookConfiguration | Allowed |
| Read secrets cluster wide | Denied |
The ability to patch both MutatingWebhookConfiguration and ValidatingWebhookConfiguration is the critical permission. With these, an attacker can redirect or intercept every API request that passes through the cluster's admission control layer.
Attack Flow
The exploitation proceeds through a clear sequence:
-
Policy creation: An attacker with permissions to create or modify ClusterPolicy resources writes a malicious policy. The apiCall block within this policy specifies a service URL pointing to an HTTP listener the attacker controls.
-
Trigger: When a Kubernetes resource matching the policy (for example, a new pod) is created, Kyverno evaluates the policy. The apiCall fires an outbound HTTP request to the attacker's endpoint.
-
Token capture: Because no explicit Authorization header is set in the policy definition, Kyverno automatically injects its admission controller ServiceAccount token into the request. The attacker's listener captures this token from the Authorization header.
-
Cluster compromise: The attacker uses the stolen token to authenticate to the Kubernetes API server. With patch permissions on webhook configurations, the attacker can hijack Kyverno's webhooks, intercept all API requests flowing through the cluster, and inject malicious containers into workloads.
SSRF Dimension
The lack of URL validation also enables Server Side Request Forgery against internal network endpoints. By pointing the apiCall URL at the cloud metadata service (169.254.169.254), an attacker can extract cloud IAM credentials from the instance metadata endpoint. This pivots the attack from Kubernetes cluster compromise into the broader cloud environment, potentially granting access to cloud storage, databases, and other services associated with the node's IAM role.
Affected Systems and Versions
The following Kyverno versions are affected:
- All versions prior to 1.16.4
- All versions in the 1.17.x branch prior to 1.17.2-rc1
- All versions in the 1.18.x branch prior to 1.18.0-rc1
The vulnerability is specifically present in deployments where:
- The apiCall feature is available in ClusterPolicy resources (default behavior).
- The admission controller ServiceAccount retains its default Helm installation permissions, which include the ability to patch webhook configurations.
- Users or service accounts in the cluster have permissions to create or modify ClusterPolicy resources.
Patched versions are 1.16.4, 1.17.2-rc1, and 1.18.0-rc1.
References
- NVD Entry for CVE-2026-41323
- GitHub Security Advisory GHSA-f9g8-6ppc-pqq4: ServiceAccount token leaked to external servers via apiCall service URL
- GitHub Advisory Database: GHSA-8wfp-579w-6r25
- Patch commit: use scoped token for request authz (main branch)
- Patch commit: backport to 1.17.x branch
- Patch commit: backport to 1.16.x branch



