Every CVE Search/ Get API key

CVE-2025-47281

Kyverno's Improper JMESPath Variable Evaluation Leads to Denial of Service

7.7 HighFix available

Kyverno is a policy engine designed for cloud native platform engineering teams. In versions 1.14.1 and below, a Denial of Service (DoS) vulnerability exists due to improper handling of JMESPath variable substitutions. Attackers with permissions to create or update Kyverno policies can craft expressions using the {{@}} variable combined with a pipe and an invalid JMESPath function (e.g., {{@ | non_existent_function }}). This leads to a nil value being substituted into the policy structure. Subsequent processing by internal functions, specifically getValueAsStringMap, which expect string values, results in a panic due to a type assertion failure (interface {} is nil, not string). This crashes Kyverno worker threads in the admission controller and causes continuous crashes of the reports controller pod. This is fixed in version 1.14.2.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
High

Exploit likelihood

0.56%Up 0.5 points since Jul 24, 2025
90%50%10%1%

What each source reports

CVE List Score used 7.7

Kyverno's Improper JMESPath Variable Evaluation Leads to Denial of Service

Kyverno is a policy engine designed for cloud native platform engineering teams. In versions 1.14.1 and below, a Denial of Service (DoS) vulnerability exists due to improper handling of JMESPath variable substitutions. Attackers with permissions to create or update Kyverno policies can craft expressions using the {{@}} variable combined with a pipe and an invalid JMESPath function (e.g., {{@ | non_existent_function }}). This leads to a nil value being substituted into the policy structure. Subsequent processing by internal functions, specifically getValueAsStringMap, which expect string values, results in a panic due to a type assertion failure (interface {} is nil, not string). This crashes Kyverno worker threads in the admission controller and causes continuous crashes of the reports controller pod. This is fixed in version 1.14.2.

Record
CVE-2025-47281
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H
Weakness
CWE-20, CWE-248
Updated
2026-11-02
EUVDEUVD-2025-22470 7.7

Kyverno is a policy engine designed for cloud native platform engineering teams. In versions 1.14.1 and below, a Denial of Service (DoS) vulnerability exists due to improper handling of JMESPath variable substitutions. Attackers with permissions to create or update Kyverno policies can craft expressions using the {{@}} variable combined with a pipe and an invalid JMESPath function (e.g., {{@ | non_existent_function }}). This leads to a nil value being substituted into the policy structure. Subsequent processing by internal functions, specifically getValueAsStringMap, which expect string values, results in a panic due to a type assertion failure (interface {} is nil, not string). This crashes Kyverno worker threads in the admission controller and causes continuous crashes of the reports controller pod. This is fixed in version 1.14.2.

Record
EUVD-2025-22470
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-r5p3-955p-5ggq 7.7

Kyverno's Improper JMESPath Variable Evaluation Lead to Denial of Service

Summary

A Denial of Service (DoS) vulnerability exists in Kyverno due to improper handling of JMESPath variable substitutions. Attackers with permissions to create or update Kyverno policies can craft expressions using the {{@}} variable combined with a pipe and an invalid JMESPath function (e.g., {{@ | non_existent_function }}).

This leads to a nil value being substituted into the policy structure. Subsequent processing by internal functions, specifically getValueAsStringMap, which expect string values, results in a panic due to a type assertion failure (interface {} is nil, not string). This crashes Kyverno worker threads in the admission controller (and can lead to full admission controller unavailability in Enforce mode) and causes continuous crashes of the reports controller pod, leading to service degradation or unavailability."

Details

The vulnerability lies in the getValueAsStringMap function within pkg/engine/wildcards/wildcards.go (specifically around line 138):

func getValueAsStringMap(key string, data interface{}) (string, map[string]string) {
    // ...
    valMap, ok := val.(map[string]interface{}) // val can be the map containing the nil value
    // ...
    for k, v := range valMap { // If valMap contains a key whose value is nil...
        result[k] = v.(string) // PANIC: v.(string) on a nil interface{}
    }
    return patternKey, result
}

When a policy contains a variable like {{@ | foo}} (where foo is not a defined JMESPath function), the JMESPath evaluation within Kyverno's variable substitution logic results in a nil value. This nil is then assigned to the corresponding field in the policy pattern (e.g., a label value).

During policy processing, ExpandInMetadata calls expandWildcardsInTag, which in turn calls getValueAsStringMap. If the data argument to getValueAsStringMap (derived from the policy pattern) contains this nil value where a string is expected, the type assertion v.(string) panics when v is nil.

Proof of Concept (PoC)

This proof of concept consists of two phases. First a malicious policy is inserted with the default validation failure action, which is Audit. In this phase the reports controller will end up in a crash loop. The admission controller will print out a similar stack trace, but only a worker crashes. The admission controller process does not crash.

In the second phase the same policy is inserted with the Enforce validation failure action. In this scenario both admission controller and the reports controller end up in a crash loop. As the admission controller crashes on incoming admission requests, it effectively makes it impossible to deploy new resources.

Tested on Kyverno v1.14.1.

  1. Prerequisites: Kubernetes cluster with Kyverno installed. Attacker has permissions to create/update ClusterPolicy or Policy resources.

  2. Create a Malicious Policy: Apply the following ClusterPolicy:

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
        name: dos-via-jmespath-nil
    spec:
        rules:
        - name: trigger-nil-panic
          match:
            any:
            - resources:
                kinds:
                - Pod
          validate:
              message: "DoS attempt via JMESPath nil substitution"
              pattern:
                metadata:
                  labels:
                    # '{{@ | non_existent_function}}' will result in a nil value for this label.
                    # This nil value causes a panic in getValueAsStringMap.
                    trigger_panic: "{{@ | non_existent_function}}"
    
  3. Verify the policy status: Make sure the policy is ready.

    k get clusterpolicy dos-via-jmespath-nil
    NAME                   ADMISSION   BACKGROUND   READY   AGE   MESSAGE
    dos-via-jmespath-nil   true        true         True    24m   Ready
    
  4. Trigger the Policy: Create any Pod…

Record
GHSA-r5p3-955p-5ggq
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H
Weakness
CWE-20, CWE-248
Updated
2026-11-02
NVD 7.7

Kyverno is a policy engine designed for cloud native platform engineering teams. In versions 1.14.1 and below, a Denial of Service (DoS) vulnerability exists due to improper handling of JMESPath variable substitutions. Attackers with permissions to create or update Kyverno policies can craft expressions using the {{@}} variable combined with a pipe and an invalid JMESPath function (e.g., {{@ | non_existent_function }}). This leads to a nil value being substituted into the policy structure. Subsequent processing by internal functions, specifically getValueAsStringMap, which expect string values, results in a panic due to a type assertion failure (interface {} is nil, not string). This crashes Kyverno worker threads in the admission controller and causes continuous crashes of the reports controller pod. This is fixed in version 1.14.2.

Record
CVE-2025-47281
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H
Weakness
CWE-20, CWE-248
Updated
2026-11-02
OSV 7.7

Kyverno's Improper JMESPath Variable Evaluation Leads to Denial of Service

Kyverno is a policy engine designed for cloud native platform engineering teams. In versions 1.14.1 and below, a Denial of Service (DoS) vulnerability exists due to improper handling of JMESPath variable substitutions. Attackers with permissions to create or update Kyverno policies can craft expressions using the {{@}} variable combined with a pipe and an invalid JMESPath function (e.g., {{@ | non_existent_function }}). This leads to a nil value being substituted into the policy structure. Subsequent processing by internal functions, specifically getValueAsStringMap, which expect string values, results in a panic due to a type assertion failure (interface {} is nil, not string). This crashes Kyverno worker threads in the admission controller and causes continuous crashes of the reports controller pod. This is fixed in version 1.14.2.

Record
CVE-2025-47281
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H
Weakness
CWE-20, CWE-248
Updated
2026-11-02
OSVGHSA-r5p3-955p-5ggq 7.7

Kyverno's Improper JMESPath Variable Evaluation Lead to Denial of Service

Summary

A Denial of Service (DoS) vulnerability exists in Kyverno due to improper handling of JMESPath variable substitutions. Attackers with permissions to create or update Kyverno policies can craft expressions using the {{@}} variable combined with a pipe and an invalid JMESPath function (e.g., {{@ | non_existent_function }}).

This leads to a nil value being substituted into the policy structure. Subsequent processing by internal functions, specifically getValueAsStringMap, which expect string values, results in a panic due to a type assertion failure (interface {} is nil, not string). This crashes Kyverno worker threads in the admission controller (and can lead to full admission controller unavailability in Enforce mode) and causes continuous crashes of the reports controller pod, leading to service degradation or unavailability."

Details

The vulnerability lies in the getValueAsStringMap function within pkg/engine/wildcards/wildcards.go (specifically around line 138):

func getValueAsStringMap(key string, data interface{}) (string, map[string]string) {
    // ...
    valMap, ok := val.(map[string]interface{}) // val can be the map containing the nil value
    // ...
    for k, v := range valMap { // If valMap contains a key whose value is nil...
        result[k] = v.(string) // PANIC: v.(string) on a nil interface{}
    }
    return patternKey, result
}

When a policy contains a variable like {{@ | foo}} (where foo is not a defined JMESPath function), the JMESPath evaluation within Kyverno's variable substitution logic results in a nil value. This nil is then assigned to the corresponding field in the policy pattern (e.g., a label value).

During policy processing, ExpandInMetadata calls expandWildcardsInTag, which in turn calls getValueAsStringMap. If the data argument to getValueAsStringMap (derived from the policy pattern) contains this nil value where a string is expected, the type assertion v.(string) panics when v is nil.

Proof of Concept (PoC)

This proof of concept consists of two phases. First a malicious policy is inserted with the default validation failure action, which is Audit. In this phase the reports controller will end up in a crash loop. The admission controller will print out a similar stack trace, but only a worker crashes. The admission controller process does not crash.

In the second phase the same policy is inserted with the Enforce validation failure action. In this scenario both admission controller and the reports controller end up in a crash loop. As the admission controller crashes on incoming admission requests, it effectively makes it impossible to deploy new resources.

Tested on Kyverno v1.14.1.

  1. Prerequisites: Kubernetes cluster with Kyverno installed. Attacker has permissions to create/update ClusterPolicy or Policy resources.

  2. Create a Malicious Policy: Apply the following ClusterPolicy:

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
        name: dos-via-jmespath-nil
    spec:
        rules:
        - name: trigger-nil-panic
          match:
            any:
            - resources:
                kinds:
                - Pod
          validate:
              message: "DoS attempt via JMESPath nil substitution"
              pattern:
                metadata:
                  labels:
                    # '{{@ | non_existent_function}}' will result in a nil value for this label.
                    # This nil value causes a panic in getValueAsStringMap.
                    trigger_panic: "{{@ | non_existent_function}}"
    
  3. Verify the policy status: Make sure the policy is ready.

    k get clusterpolicy dos-via-jmespath-nil
    NAME                   ADMISSION   BACKGROUND   READY   AGE   MESSAGE
    dos-via-jmespath-nil   true        true         True    24m   Ready
    
  4. Trigger the Policy: Create any Pod…

Record
GHSA-r5p3-955p-5ggq
CVSS 3.1
7.7 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H
Weakness
CWE-20, CWE-248
Updated
2026-11-02
OSVBIT-kyverno-2025-47281 No score

Kyverno's Improper JMESPath Variable Evaluation Leads to Denial of Service

Kyverno is a policy engine designed for cloud native platform engineering teams. In versions 1.14.1 and below, a Denial of Service (DoS) vulnerability exists due to improper handling of JMESPath variable substitutions. Attackers with permissions to create or update Kyverno policies can craft expressions using the {{@}} variable combined with a pipe and an invalid JMESPath function (e.g., {{@ | non_existent_function }}). This leads to a nil value being substituted into the policy structure. Subsequent processing by internal functions, specifically getValueAsStringMap, which expect string values, results in a panic due to a type assertion failure (interface {} is nil, not string). This crashes Kyverno worker threads in the admission controller and causes continuous crashes of the reports controller pod. This is fixed in version 1.14.2.

Record
BIT-kyverno-2025-47281
Updated
2026-11-02
OSVGO-2025-3823 No score

Kyverno's Improper JMESPath Variable Evaluation Lead to Denial of Service in github.com/kyverno/kyverno

Kyverno's Improper JMESPath Variable Evaluation Lead to Denial of Service in github.com/kyverno/kyverno

Record
GO-2025-3823
Updated
2026-11-02
OSVopenSUSE-SU-2025:15405-1 No score

govulncheck-vulndb-0.0.20250730T213748-1.1 on GA media

These are all security issues fixed in the govulncheck-vulndb-0.0.20250730T213748-1.1 package on the GA media of openSUSE Tumbleweed.

Record
openSUSE-SU-2025:15405-1
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
github.com/kyverno/kyverno
Go
through 1.14.1
1.14.2
kyverno
Bitnami
before 1.14.2
1.14.2
github.com/kyverno/kyverno
Go
before 1.14.2
1.14.2
govulncheck-vulndb
openSUSE:Tumbleweed
From an advisory covering 56 CVEs
before 0.0.20250730T213748-1.1
0.0.20250730T213748-1.1

History

History
RecordedChangedSources
affected, facts
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2025-47281 is a high vulnerability (CVSS 7.7) in Kyverno, published July 22, 2025. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.56%, the 46th percentile. Fixed in github.com/kyverno/kyverno 1.14.2.

References

Show 56 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open