GitHub Security Advisory: GHSA-3wf5-g532-rcrr
Package: github.com/argoproj/argo-workflows (GO)
Severity: HIGH (CVSS 0.0)
CWE: CWE-863: Incorrect Authorization
Vulnerable versions: >= 2.9.0, < 3.0.0
Patched in: unpatched

Summary: Argo Workflows: WorkflowTemplate Security Bypass via podSpecPatch in Strict/Secure Reference Mode

Details:
## Summary

A user who can submit Workflows can completely bypass all security settings defined in a `WorkflowTemplate` by including a `podSpecPatch` field in their Workflow submission. This works even when the controller is configured with `templateReferencing: Strict`, which is specifically documented as a mechanism to restrict users to admin-approved templates. The `podSpecPatch` field on a submitted Workflow takes precedence over the referenced `WorkflowTemplate` during spec merging and is applied directly to the pod spec at creation time with no security validation.

## Details

Three issues combine to create this vulnerability:

1. Merge priority order:`JoinWorkflowSpec` merges specs with the priority order Workflow Spec > WorkflowTemplate Spec > WorkflowDefault Spec. Because `podSpecPatch` is a plain string field, the Workflow's value replaces the WorkflowTemplate's value.

2. No security validation on `podSpecPatch`: `ApplyPodSpecPatch()` only validates that the patch is syntactically valid JSON conforming to the Kubernetes `PodSpec` schema. No checks are performed for dangerous security settings such as `privileged: true`.

3. `templateReferencing: Strict` does not restrict `podSpecPatch`: Strict mode only checks whether `WorkflowTemplateRef` is set. If it is, the Workflow passes validation regardless of what other fields (including `podSpecPatch`) are present.

## PoC

### Prerequisites

A local Kubernetes cluster with Argo Workflows installed. The instructions below use [kind](https://kind.sigs.k8s.io/).

#### 1. Create a kind cluster and install Argo Workflows

```bash
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
```

Note: `--server-side` is required because some CRDs exceed the client-side annotation size limit.

Wait for the controller to be ready:

```bash
kubectl wait -n argo --for=condition=Ready pod -l app=workflow-controller --timeout=120s
```

#### 2. Enable `templateReferencing: Strict`

Patch the workflow controller configmap to enforce Strict mode:

```bash
kubectl patch configmap workflow-controller-configmap -n argo --type merge \
  -p '{"data":{"workflowRestrictions":"templateReferencing: Strict\n"}}'
```

Restart the controller to pick up the new config:

```bash
kubectl rollout restart deployment workflow-controller -n argo
kubectl wait -n argo --for=condition=Ready pod -l app=workflow-controller --timeout=120s
```

#### 3. Verify Strict mode is active

Attempt to submit a standalone Workflow (no `workflowTemplateRef`). It should be rejected:

```bash
cat <<'EOF' | kubectl create -n argo -f -
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: strict-test-
spec:
  entrypoint: test
  templates:
  - name: test
    container:
      image: alpine
      command: [echo, "hello"]
EOF
```

The Workflow will be accepted by the API server but the controller will