Kyverno Service Account Token Leak via API Call
Kyverno's apiCall serviceCall helper implicitly injects the Kyverno controller service account token into requests when policies lack an explicit Authorization header, allowing exfiltration to attacker-controlled endpoints and unauthorized actions.
A vulnerability exists in Kyverno versions prior to 1.17.0 where the apiCall and serviceCall helpers automatically inject the Kyverno controller’s service account token into outgoing requests. This occurs when a Kyverno policy does not explicitly define an Authorization header for the request. Because the destination URL for these API calls is policy-controlled via context.apiCall.service.url, a malicious actor could create or modify a ClusterPolicy or GlobalContextEntry to direct these requests—and thus the service account token—to an attacker-controlled endpoint. This vulnerability allows for token exfiltration and subsequent unauthorized actions, depending on the RBAC permissions granted to the Kyverno service account. This issue is limited to ClusterPolicy and global context usage, as namespaced policies are blocked from servicecall usage.
Attack Chain
- Attacker gains the ability to create or modify
ClusterPolicyobjects, potentially by compromising a GitOps repository or controller managing Kyverno policies. - Attacker crafts a malicious
ClusterPolicythat uses theapiCallorserviceCallfeature. - The policy specifies a URL for the
context.apiCall.service.urlthat points to an attacker-controlled endpoint designed to capture the incoming request. - The crafted policy does not define an explicit
Authorizationheader for theapiCallorserviceCall. - When the policy is triggered, Kyverno’s
executor.addHTTPHeadersfunction detects the missingAuthorizationheader. - Kyverno reads the service account token from
/var/run/secrets/kubernetes.io/serviceaccount/token. - Kyverno injects the service account token into the request header as
Authorization: Bearer <token>. - The request, including the Kyverno service account token, is sent to the attacker-controlled endpoint, allowing the attacker to exfiltrate the token.
Impact
Successful exploitation of this vulnerability results in the exfiltration of the Kyverno controller service account token. The severity of the impact depends on the RBAC roles and permissions assigned to the Kyverno service account within the Kubernetes cluster. With the stolen token, an attacker can perform any action that the Kyverno service account is authorized to perform, potentially leading to cluster-wide compromise, data breaches, or denial-of-service conditions. The number of affected clusters would depend on the number of Kyverno deployments using vulnerable versions.
Recommendation
- Upgrade Kyverno to version 1.17.0 or later to patch the vulnerability (go/github.com/kyverno/kyverno).
- Implement monitoring to detect modifications to
ClusterPolicyresources, especially those utilizingapiCallorserviceCallto arbitrary URLs, to quickly identify potentially malicious policy changes. - Deploy the provided Sigma rule to detect unexpected outbound network connections from the Kyverno pod that may indicate token exfiltration.
- As a workaround, set explicit
Authorizationheaders in allapiCallandserviceCallpolicies to prevent the implicit token injection (see workarounds).
Detection coverage 2
Detect Outbound Connection from Kyverno Pod
highDetects outbound network connections originating from the Kyverno pod, which could indicate potential token exfiltration.
Detect ClusterPolicy Creation/Update with apiCall
mediumDetects the creation or update of ClusterPolicy resources that utilize the apiCall or serviceCall functionality, which could be a precursor to token exfiltration.
Detection queries are kept inside the platform. Get full rules →
Indicators of compromise
5
url
| Type | Value |
|---|---|
| url | https://github.com/kyverno/kyverno |
| url | https://github.com/kyverno/kyverno/blob/17aeb52337fd66adb0c8126213ba076612a287a7/pkg/engine/apicall/executor.go#L150-L173 |
| url | https://github.com/kyverno/kyverno/blob/17aeb52337fd66adb0c8126213ba076612a287a7/pkg/engine/apicall/apiCall.go#L67-L83 |
| url | https://github.com/user-attachments/files/25352288/poc.zip |
| url | https://github.com/user-attachments/files/25352289/PR_DESCRIPTION.md |