GitHub Advisoryadvisory · Go

GHSA-qr4g-8hrp-c4rw Kyverno has unrestricted outbound requests in Kyverno apiCall enabling SSRF

HIGH Published 2026-04-14 Modified 2026-04-14 Official page ↗
Ecosystem
Go
Packages
github.com/kyverno/kyverno
Severity
High
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
Weaknesses
CWE-918
Reviewed
2026-04-14

Affected packages

• Go github.com/kyverno/kyverno: <= 1.17.1 (no fix yet)

Description

Summary A Server-Side Request Forgery (SSRF) vulnerability in Kyverno allows authenticated users to induce the admission controller to send arbitrary HTTP requests to attacker-controlled endpoints. When a `ClusterPolicy` uses `apiCall.service.url` with variable substitution (e.g. `{{request.object.*}}`), user-controlled input can influence the request target. The Kyverno admission controller executes these requests from its privileged network position without enforcing any validation or network restrictions. The issue becomes non-blind SSRF, as response data from internal services can be reflected back to the user via admission error messages. --- Details Kyverno supports variable substitution in `apiCall.service.url`, a documented feature intended to enable dynamic external lookups during admission control. However, the current implementation lacks fundamental safeguards in the HTTP execution path: Missing protections • No URL validation User-controlled input is directly embedded into the request URL without validation or normalization. • No IP filtering Requests can target: • Loopback (`127.0.0.1`) • Link-local (`169.254.0.0/16`) • Cloud metadata services (e.g. AWS IMDS) • Internal ClusterIP services • Redirect handling not restricted The Go HTTP client uses default redirect behavior (`CheckRedirect == nil`), allowing up to 10 redirects without re-validation of the target. • Response data reflection in admission errors Response bodies are propagated back to the user in admission responses under certain conditions. Non-blind SSRF behavior The vulnerability is non-blind through two mechanisms: 1. Non-2xx responses Response body is returned in admission error messages (e.g. `executor.go:98-101`) 2. 2xx responses with non-JSON content Parsing failures (JSON/JMESPath) include response snippets in error output This allows attackers to retrieve data from internal services directly via `kubectl` output. --- PoC Preconditions 1. A `ClusterPolicy` using: ```yaml apiCall: service: url: "http://{{ request.object.metadata.annotations.target }}" ``` 2. An authenticated user able to create matching resources (e.g. Pods) --- Step 1 — Create malicious resource ```yaml apiVersion: v1 kind: Pod metadata: name: ssrf-test annotations: target: "169.254.169.254/latest/meta-data/iam/security-credentials/" spec: containers: • name: test image: nginx ``` --- Step 2 — Apply resource ```bash kubectl apply -f pod.yaml ``` --- Step 3 — Observe output Example output: ```text Error from server: admission webhook "kyverno" denied the request: failed to process apiCall: ``` --- Variations • Internal services: http://kubernetes.default.svc • Loopback: http://127.0.0.1:8080 • Redirect chains to bypass naive filters --- Impact Vulnerability class • Server-Side Request Forgery (SSRF) • Non-blind data exfiltration Affected scope • Kubernetes clusters using Kyverno policies with `apiCall.service.url` and variable substitution Impact details • Access to internal services (ClusterIP, localhost) • Access to cloud metadata endpoints (e.g. IMDSv1 → credential exposure) • Internal network reconnaissance • Multi-tenant boundary weakening This issue can be combined with automatic ServiceAccount token forwarding (reported separately) to form a critical attack chain.

Related

Weakness · CWE (1)

  • CWE-918 Server-Side Request Forgery weakness

References