CVE
CVE-2026-62290, CVE-2026-119115, CVE-2026-118758, CVE-2026-118759, CVE-2026-118760, CVE-2026-118761, CVE-2026-119127, CVE-2026-119128, CVE-2026-119129, CVE-2026-9800
CWE
CWE-863, CWE-287, CWE-22, CWE-409, CWE-347, CWE-640
Affected Surface
- Kubernetes `cert-manager` (`github.com/cert-manager/cert-manager`) versions `>= 1.18.0, < 1.19.6` and `>= 1.20.0-alpha.0, < 1.20.3` (`CVE-2026-62290` / `GHSA-8rvj-mm4h-c258`, CVSS 7.3 High)
- AWS Private CA Connector for Kubernetes (`github.com/cert-manager/aws-privateca-issuer`) versions `< 1.10.1` (`CVE-2026-119115` / `GHSA-hjrh-q6pg-mh82` / `AWS-2026-156`, CVSS 8.5 High)
- Kubeflow Pipelines (`github.com/kubeflow/pipelines`) versions `< 2.18.0` (`CVE-2026-118758`, `CVE-2026-118759`, `CVE-2026-118761`, CVSS 7.5 High) and `>= 0.5.1, < 2.17.0` (`CVE-2026-118760`, CVSS 6.5 Medium)
- ZITADEL (`github.com/zitadel/zitadel` Login V2) versions `>= 4.0.0, < 4.19.5` (`CVE-2026-119127`, `CVE-2026-119128`) and `>= 3.0.0, <= 3.4.15` / `>= 4.0.0, < 4.19.5` (`CVE-2026-119129`, CVSS 8.1 High)
- Keycloak (`org.keycloak:keycloak-services < 26.6.4` and `org.keycloak:keycloak-policy-enforcer < 26.0.10`, `CVE-2026-9800` / `GHSA-f5p5-6xmx-p252`, CVSS 8.1 High)
TL;DR
On 29 October 2026, ten high-severity vulnerabilities were disclosed across Kubernetes certificate controllers, ML pipeline servers, and OIDC/IAM platforms:
- Kubernetes
cert-manager(CVE-2026-62290/GHSA-8rvj-mm4h-c258, CVSS 7.3 High, fixed in1.19.6and1.20.3) andaws-privateca-issuer(CVE-2026-119115/GHSA-hjrh-q6pg-mh82/AWS-2026-156, CVSS 8.5 High, fixed in1.10.1):- In
cert-manager, the defaultcert-manager-editaggregateClusterRolegranted namespace userscreatepermission onchallenges.acme.cert-manager.io, andValidateChallenge()did not verify that aChallengewas owned by a cert-managerOrder. A tenant could create a standaloneChallengereferencing aClusterIssuerwith an attacker-controlledChallenge.spec.solver, bypassingdnsZones/dnsNamessolver selectors and forcing cert-manager to sendClusterIssueracme-dnscredentials (X-Api-UserandX-Api-Key) to an attacker’s host or mutate unauthorized DNS zones. - In
aws-privateca-issuer(< 1.10.1),util.GetIssuer()looked up a namespacedAWSPCAIssuerfirst and, whenever that lookup returned an error, fell back to fetching a cluster-scopedAWSPCAClusterIssuerof the same name regardless ofissuerRef.kind. A tenant whoseCertificateRequestapproval policy only allowed namespacedAWSPCAIssuerobjects could name aClusterIssuerunderkind: AWSPCAIssuerand obtain certificates (including subordinate CA certificates) from the cluster-wide AWS Private CA.
- In
- Kubeflow Pipelines
< 2.18.0(CVE-2026-118758,CVE-2026-118759,CVE-2026-118760, andCVE-2026-118761, CVSS 7.5 High): Four flaws in the Kubeflow Pipelines API server and frontend allowed callers to traverse outside mounted volumes onGET /artifacts/get?source=volume(CVE-2026-118758), read logs of arbitrary pods in a run’s namespace viaGET /apis/v1alpha1/runs/{run_id}/nodes/{node_id}/logwithoutreadLogauthorization orpipeline/runidpod-label checks (CVE-2026-118759), bypass multi-user namespace checks on frontend artifact routes (CVE-2026-118760), and crash the API server or persistence agent with pre-auth ZIP or PAX-header tar bombs (CVE-2026-118761). - ZITADEL Login V2
< 4.19.5(CVE-2026-119127,CVE-2026-119128, andCVE-2026-119129, CVSS 8.1 High / v4.0 up to 9.1 Critical) and Keycloak< 26.6.4/< 26.0.10(CVE-2026-9800/GHSA-f5p5-6xmx-p252, CVSS 8.1 High): ZITADEL Login V2 computed itsverificationCheckcookie as an unsaltedsha256(userId:fingerprintId)hash that an unauthenticated attacker could forge offline (CVE-2026-119128), silently dropped malformedX-Zitadel-Public-Hostheaders to bypass the trusted-domain check and poison password-reset emails (CVE-2026-119127), and auto-approved OAuth 2.0 device authorizations as soon as a signed-in user visited/signedin(CVE-2026-119129). In Keycloak, Policy Enforcer compared request URIs against the configuredaccess-denied-pathusing an unanchored match, allowing any authenticated user to bypass all role, scope, and UMA policies by embedding the access-denied path segment or query string in the target URL (CVE-2026-9800).
What to do now: Upgrade cert-manager to >= 1.20.3 or >= 1.19.6, aws-privateca-issuer to >= 1.10.1 (v1.10.1-eksbuild.1 on EKS), Kubeflow Pipelines to >= 2.18.0, ZITADEL to >= 4.19.5 (and configure a 32+ character ZITADEL_SESSION_COOKIE_SECRET), and keycloak-services / keycloak-policy-enforcer to >= 26.6.4 / >= 26.0.10.
Affected packages and projects
| Ecosystem | Package / Component | CVE / Advisory | Severity | Affected versions | Fixed version(s) | Vulnerable path |
|---|---|---|---|---|---|---|
| Go / Helm | github.com/cert-manager/cert-manager | CVE-2026-62290 (GHSA-8rvj-mm4h-c258) | CVSS 7.3 High | >= 1.18.0, < 1.19.6; >= 1.20.0-alpha.0, < 1.20.3 | 1.19.6, 1.20.3 | deploy/charts/cert-manager/templates/rbac.yaml, pkg/issuer/acme/dns/dns.go |
| Go / Helm | github.com/cert-manager/aws-privateca-issuer | CVE-2026-119115 (GHSA-hjrh-q6pg-mh82, AWS-2026-156) | CVSS 8.5 High | < 1.10.1 | 1.10.1 (v1.10.1-eksbuild.1) | pkg/controllers/certificaterequest_controller.go, pkg/util/issuers.go (GetIssuer) |
| Go / Node.js | github.com/kubeflow/pipelines | CVE-2026-118758 (GHSA-2fg9-fx2f-439r), CVE-2026-118759 (GHSA-wg5q-x4j9-qm54), CVE-2026-118761 (GHSA-8fmv-6rg5-5924), CVE-2026-118760 (GHSA-vjhf-6c8f-qhwj) | CVSS 7.5 High / 6.5 Medium | < 2.18.0 (118760 fixed in 2.17.0) | 2.18.0 | frontend/server/handlers/artifacts.ts, backend/src/apiserver/resource/resource_manager.go (ReadLog), server/util.go |
| Go / Next.js | github.com/zitadel/zitadel (Login V2) | CVE-2026-119127 (GHSA-mchc-246r-6m76), CVE-2026-119128 (GHSA-84fg-x5h4-w8xv), CVE-2026-119129 (GHSA-qj3q-235g-qr6w) | CVSS 8.1 / 7.4 High (v4.0 up to 9.1 Critical) | >= 4.0.0, < 4.19.5 (119129 also affects 3.0.0..3.4.15) | 4.19.5 | internal/api/http/middleware/origin_interceptor.go, apps/login/src/lib/verification-check.ts, apps/login/src/app/(login)/device/consent/page.tsx |
| Maven | org.keycloak:keycloak-services, org.keycloak:keycloak-policy-enforcer | CVE-2026-9800 (GHSA-f5p5-6xmx-p252) | CVSS 8.1 High | keycloak-services < 26.6.4, keycloak-policy-enforcer < 26.0.10 | 26.6.4, 26.0.10 | Keycloak Policy Enforcer URI comparison (access-denied-path check) |
Technical analysis
1. cert-manager (CVE-2026-62290) and aws-privateca-issuer (CVE-2026-119115): cross-scope ClusterIssuer abuse
In cert-manager, normal ACME certificate issuance flows from a Certificate to an Order, where the Order controller evaluates the referenced Issuer or ClusterIssuer’s solvers[].selector rules (dnsZones, dnsNames, matchLabels) and copies the chosen solver config into a child Challenge resource (acme.cert-manager.io/v1).
However, two things were true in cert-manager 1.18.0 through 1.19.5 and 1.20.0 through 1.20.2:
- The Helm chart’s
cert-manager-editaggregateClusterRole(granted by default to namespaceadminandeditroles) includedverbs: ["create", "delete", "deletecollection", "patch", "update"]onchallenges.acme.cert-manager.io. - When reconciling a
Challenge,pkg/issuer/acme/dns/dns.goloaded credentials from theClusterIssuerresource namespace (cert-manager) or ambient cloud credentials wheneverchallenge.Spec.IssuerRef.Kind == "ClusterIssuer", but read the DNS01 provider configuration fromchallenge.Spec.Solveron the untrustedChallengeobject itself.
A tenant service account with challenges create permission in any namespace could apply a standalone Challenge referencing ClusterIssuer/cluster-prod while setting spec.solver.dns01.acmeDNS.host: https://attacker[.]example/acmedns and accountSecretRef.name: cluster-acmedns-account. When the Challenge controller called Present(), it loaded cluster-acmedns-account from the cert-manager namespace and sent the secret’s X-Api-User and X-Api-Key headers to attacker[.]example (commit 6bda47297c removes create on challenges and create/patch/update on orders from the aggregate ClusterRole).
In aws-privateca-issuer (< 1.10.1, CVE-2026-119115), GetIssuer() in pkg/util/issuers.go ignored cr.Spec.IssuerRef.Kind whenever a namespaced lookup failed:
--- a/pkg/util/issuers.go
+++ b/pkg/util/issuers.go
@@ -29,22 +30,38 @@ var realtimeClock clock.Clock = clock.RealClock{}
-// GetIssuer returns either an AWSPCAClusterIssuer or AWSPCAIssuer by its name
-func GetIssuer(ctx context.Context, client client.Client, name types.NamespacedName) (api.GenericIssuer, error) {
- iss := new(api.AWSPCAIssuer)
- err := client.Get(ctx, name, iss)
- if err != nil {
- ciss := new(api.AWSPCAClusterIssuer)
- cname := types.NamespacedName{
- Name: name.Name,
- }
- err = client.Get(ctx, cname, ciss)
In pkg/controllers/certificaterequest_controller.go, issuerName.Namespace was cleared only when cr.Spec.IssuerRef.Kind == "AWSPCAClusterIssuer", so passing kind: AWSPCAIssuer (or kind: Issuer) with name: prod-root-ca caused client.Get(ctx, {Namespace: "tenant", Name: "prod-root-ca"}, iss) to return NotFound and immediately fall through to fetching the cluster-wide AWSPCAClusterIssuer prod-root-ca. Because RBAC and cert-manager CertificateRequestPolicy / approver rules commonly allow tenants to approve requests referencing namespaced AWSPCAIssuer objects while restricting AWSPCAClusterIssuer, a tenant could bypass approval policy and mint certificates from the cluster-scoped AWS Private CA. Commit 9ae225b695 (v1.10.1) requires issuerRef.kind to be AWSPCAIssuer or AWSPCAClusterIssuer and queries only that exact resource kind.
2. Kubeflow Pipelines 2.18.0 (CVE-2026-118758, CVE-2026-118759, CVE-2026-118760, and CVE-2026-118761)
Kubeflow Pipelines 2.18.0 patches four vulnerabilities across its TypeScript frontend proxy and Go API server:
- Volume artifact path traversal (
CVE-2026-118758, commit4d9bc5ab12): Infrontend/server/handlers/artifacts.ts,GET /artifacts/get?source=volume&bucket=<pvc>&key=<path>resolved the file path without confining it to the mounted PVC root, anddomain_from_url()indomain-checker.tsused a regex (match(/^(?:https?:\/\/)?(?:[^@/\n]+@)?([^:/?\n]+)/)) that acceptedfile:///etc/passwdwhen the domain allowlist was^.*$. Version2.18.0opens volume artifacts viaopenFileWithinRoot()and parses URLs withnew URL()restricting schemes tohttp:andhttps:. - Cross-pod log disclosure via
ReadRunLogV1(CVE-2026-118759, commitbe4723e337): Inbackend/src/apiserver/resource/resource_manager.go,ReadLog(ctx, runId, nodeId, follow, dst)looked up the namespace ofrunIdand then streamed logs from the pod namednodeIdin that namespace without authorizing the caller againstrunIdor checking whether the podnodeIdactually belonged torunId:
Version--- a/backend/src/apiserver/resource/resource_manager.go +++ b/backend/src/apiserver/resource/resource_manager.go @@ -1505,6 +1505,15 @@ func (r *ResourceManager) ReadLog(ctx context.Context, runId string, nodeId stri -func (r *ResourceManager) readRunLogFromPod(ctx context.Context, namespace string, nodeId string, follow bool, dst io.Writer) error { +func (r *ResourceManager) readRunLogFromPod(ctx context.Context, runID string, namespace string, nodeID string, follow bool, dst io.Writer) error { + // The caller controls nodeID, so confirm the pod was created by this run + // before streaming, otherwise the run only selects a namespace and any pod + // in it could be read with the API server's credentials. + pod, err := r.k8sCoreClient.PodClient(namespace).Get(ctx, nodeID, v1.GetOptions{})2.18.0authorizes a dedicatedreadLogRBAC verb and verifies that the pod’spipeline/runidlabel matchesrunIDbefore streaming. - Pre-auth ZIP and PAX-header tar bomb OOM (
CVE-2026-118761, commits1121d9a081andba9ae72cc8): Multipart pipeline uploads decompressed.zipand.tar.gzarchives into memory before running namespace authorization, andtar.Reader.Next()decompressed unbounded PAX extended headers (TypeXHeader) before reaching the per-file size check. Version2.18.0wraps bothgzipReaderand entry readers inio.LimitedReaderwith an overflow-safeArchiveTraversalBudget(int64(maxFileLength)) + 1sentinel.
3. ZITADEL 4.19.5 (CVE-2026-119127, CVE-2026-119128, CVE-2026-119129) and Keycloak 26.6.4 (CVE-2026-9800)
In ZITADEL (4.0.0 before 4.19.5), three flaws affected the Next.js Login V2 application and Go origin interceptor:
- Forgeable
verificationCheckandlinkFingerprintcookies (CVE-2026-119128/GHSA-84fg-x5h4-w8xv, commite32ba7aa69): After a user verified an email or invite code, Login V2 set averificationCheckcookie equal tosha256(userId:fingerprintId)(and usedsha256(sessionId + fingerprintId)for IdP account linking). Because bothuserIdand the client-sidefingerprintIdcookie were known to the client without any server secret, an unauthenticated attacker could computesha256(victimUserId:attackerFingerprint)offline, skip the email/invite verification step for any user without an enrolled authentication factor, and register their own password or passkey on the account. Version4.19.5replaces the raw SHA-256 digest with a 5-minute HMAC proof (createSignedProof) keyed via HKDF fromZITADEL_SESSION_COOKIE_SECRET. - Public-host header sanitization fallback bypass (
CVE-2026-119127/GHSA-mchc-246r-6m76, commit6493aa908c): Ininternal/api/http/middleware/origin_interceptor.go,composeDomainContext()extractedpublicHostfromX-Zitadel-Public-Host/X-Forwarded-Host. If the header contained a trailing slash or userinfo (such asX-Zitadel-Public-Host: evil[.]com:443/),hostFromRequest()returnedpublicHost = "", which caused ZITADEL to skip theTrustedDomainscheck while Login V2 still used the raw header to construct password-reset and invite links:--- a/internal/api/http/middleware/origin_interceptor.go +++ b/internal/api/http/middleware/origin_interceptor.go @@ -30,11 +30,17 @@ func composeDomainContext(r *http.Request, enforceHttps bool, instanceDomainHead - instanceHost, instanceProto := hostFromRequest(r, instanceDomainHeaders) - publicHost, publicProto := hostFromRequest(r, publicDomainHeaders) + instanceHost, instanceProto, _ := hostFromRequest(r, instanceDomainHeaders) + publicHost, publicProto, rawPublicHost := hostFromRequest(r, publicDomainHeaders) if instanceHost == "" { instanceHost = r.Host } + if publicHost == "" && rawPublicHost != "" { + publicHost = rawPublicHost + } - Consent-less OAuth 2.0 Device Authorization approval (
CVE-2026-119129/GHSA-qj3q-235g-qr6w, commita618740b57): Navigating a signed-in user to/signedin?requestId=device_...automatically calledcompleteDeviceAuthorization()on page render without displaying a consent prompt or verifying that the browser had entered theuser_code. Version4.19.5moves approval to an explicit server action on/device/consentbound by a short-liveddeviceCodeCheckcookie.
Separately, in Keycloak (org.keycloak:keycloak-services < 26.6.4 and org.keycloak:keycloak-policy-enforcer < 26.0.10, CVE-2026-9800 / GHSA-f5p5-6xmx-p252), Policy Enforcer bypassed all role, scope, and UMA permission checks whenever the incoming request URI contained the configured access-denied-path string as a path segment or query parameter, allowing any authenticated user to reach protected endpoints.
Detection and remediation
# 1. Check Kubernetes clusters for vulnerable cert-manager and aws-privateca-issuer versions and direct Challenges
kubectl get deployment -n cert-manager -o wide 2>/dev/null || true
kubectl get challenges.acme.cert-manager.io -A -o json 2>/dev/null | \
jq -r '.items[] | select((.metadata.ownerReferences // []) | length == 0) | "\(.metadata.namespace)/\(.metadata.name) -> issuer=\(.spec.issuerRef.kind)/\(.spec.issuerRef.name)"'
# 2. Audit CertificateRequests where issuerRef.kind is missing or does not match AWSPCAIssuer / AWSPCAClusterIssuer
kubectl get certificaterequests.cert-manager.io -A -o json 2>/dev/null | \
jq -r '.items[] | select(.spec.issuerRef.group == "awspca.cert-manager.io" and (.spec.issuerRef.kind != "AWSPCAIssuer" and .spec.issuerRef.kind != "AWSPCAClusterIssuer")) | "\(.metadata.namespace)/\(.metadata.name): kind=\(.spec.issuerRef.kind)"'
# 3. Check Go and Maven lockfiles for kubeflow/pipelines, zitadel, and keycloak
rg -n 'cert-manager|aws-privateca-issuer|kubeflow/pipelines|zitadel|keycloak-(services|policy-enforcer)' \
go.mod pom.xml build.gradle* Chart.yaml values.yaml 2>/dev/null
- Upgrade
cert-managerto>= 1.20.3or>= 1.19.6and audit any existing customRoleorClusterRolemanifests to ensure tenant service accounts do not holdcreatepermissions onchallenges.acme.cert-manager.ioororders.acme.cert-manager.io. If any ownerlessChallengeresource was created in your cluster, rotate theClusterIssuerDNS01 provider credentials immediately. - Upgrade
aws-privateca-issuerto>= 1.10.1(or the EKS add-on tov1.10.1-eksbuild.1), and update everyCertificate,CertificateRequest, and Ingress annotation to specifyissuerRef.kind: AWSPCAIssuerorAWSPCAClusterIssuerexplicitly. - Upgrade Kubeflow Pipelines to
>= 2.18.0so volume artifact reads are confined to the volume root,ReadRunLogV1enforcesreadLogRBAC and podpipeline/runidlabels, and archive uploads enforceArchiveTraversalBudget. - Upgrade ZITADEL to
>= 4.19.5and set a dedicated 32+ characterZITADEL_SESSION_COOKIE_SECRET(openssl rand -base64 32) on the Login V2 deployment. - Upgrade Keycloak (
org.keycloak:keycloak-servicesto>= 26.6.4andorg.keycloak:keycloak-policy-enforcerto>= 26.0.10).
Timeline
- 2026-10-13:
aws-privateca-issuerreleasesv1.10.1(9ae225b695). - 2026-10-15: ZITADEL commits fixes for
CVE-2026-119127(6493aa908c),CVE-2026-119128(e32ba7aa69), andCVE-2026-119129(a618740b57) inv4.19.5. - 2026-10-28 to 2026-10-29:
cert-managerreleasesv1.19.6andv1.20.3(6bda47297c,b37dbf01ec), Kubeflow Pipelines releases2.18.0(4d9bc5ab12,be4723e337,1121d9a081,ba9ae72cc8), and NVD, AWS (2026-156-AWS), and the GitHub Advisory Database publish all ten advisories.
From research to remediation
Check whether this pattern exists in your codebase
Turn this research into a remediation workflow. Use AI-native static analysis to find similar application vulnerabilities and generate review-ready fixes.
References
- cert-manager advisory GHSA-8rvj-mm4h-c258 (CVE-2026-62290: direct ACME Challenge bypasses ClusterIssuer solver policy) and commit 6bda47297c
- AWS Security Bulletin 2026-156-AWS and aws-privateca-issuer commit 9ae225b695 (CVE-2026-119115 / GHSA-hjrh-q6pg-mh82)
- Kubeflow Pipelines commits 4d9bc5ab12 (#13677), be4723e337 (#13684), 1121d9a081 (#14171), and ba9ae72cc8 (#14186)
- ZITADEL v4.19.5 commits a618740b57, e32ba7aa69, and 6493aa908c (CVE-2026-119127, CVE-2026-119128, CVE-2026-119129)
- Keycloak advisory GHSA-f5p5-6xmx-p252 (CVE-2026-9800: Policy Enforcer authorization bypass)