Where
-Infinity
0
Severity
7

Finding The v2 compiler (backend/src/v2/compiler/argocompiler/securitycontext.go) forcibly applies PSS-restricted defaults to every container it generates. The kubernetesexecutorconfig proto explicitly removed privileged/addcapabilities/dropcapabilities. All of this is bypassed when a tenant uploads a document whose TypeMeta matches argoproj.io/v1alpha1 / Workflow: the API server unmarshals it into a full workflowapi.Workflow struct and creates it via its own ServiceAccount (which holds workflows: create). The Argo workflow-controller then materializes pods containing whatever the tenant wrote: spec.templates[].container.securityContext.privileged: true, spec.hostNetwork: true, spec.hostPID: true, spec.volumes[].hostPath.path: /, arbitrary initContainers, and spec.serviceAccountName.

Files:

backend/src/apiserver/template/template.go:62-67 — inferTemplateFormat routes any V1 document

backend/src/apiserver/template/template.go:153-157 — NewArgoTemplate

backend/src/apiserver/template/argotemplate.go:209-230 — ValidateWorkflow runs structural lint only, no security-context filtering

backend/src/apiserver/template/argotemplate.go:30-91 — RunWorkflow deep-copies user spec verbatim

Framework: OWASP K8s K01/K02; ASVS V5.2.5 CWE: CWE-1336 (Improper Neutralization of Special Elements Used in a Template Engine) / CWE-668 (Exposure of Resource to Wrong Sphere) CVSS v3.1: 7.6 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L) – High

Confused-Deputy Aspect The pipeline submitter need not hold create workflows or use scc/privileged. The ml-pipeline SA creates the Workflow on their behalf, and the workflow-controller SA creates the Pod. Whether the pod is admitted depends solely on namespace SCC/PSA. In RHOAI data-science-project namespaces that bind GPU operators or anyuid/privileged SCC for CUDA workloads, this yields node-root.

Verification Confirmed that the V1 path is still reachable in RHOAI/DSPO deployments:

DSPO passes no flags or env vars to disable V1 template handling

The Argo CRD deployed by DSPO registers v1alpha1 as served:true and storage:true

No DSPA CR field, operator config, or feature flag restricts template formats

Impact A namespace editor can achieve node-root by uploading a raw Argo Workflow with hostPath, hostNetwork, privileged:true via the V1 API path. The API server creates the Workflow CR as a confused deputy.

Remediation Disable the V1 Argo template path in RHOAI builds (feature flag, fail inferTemplateFormat to V1 with NewInvalidInputError)

If V1 must remain, add a sanitizer in RunWorkflow/ValidateWorkflow that strips hostPath/hostNetwork/hostPID/hostIPC, forces securityContext.privileged=false, drops capabilities, and clears serviceAccountName

Operator-side: ensure DSP namespaces carry pod-security.kubernetes.io/enforce: restricted and that pipeline-runner SA is not bound to privileged/anyuid SCC

First published (updated )
Severity
4

Finding setDefaultServiceAccount honours, in priority order: (1) modelRun.ServiceAccount from the API request body, (2) the serviceAccountName already embedded in the uploaded Workflow, (3) the configured default. There is no SubjectAccessReview verifying the caller can use serviceaccounts/<name> or impersonate it.

A tenant can set serviceaccount in their CreateRun request to any SA in the namespace – including ds-pipeline-<dspa> (the API server's own SA, which can create workflows and delete pods) or pipeline-runner (which has secrets:get, pods/exec:).

This affects both V1 and V2 paths.

Files:

backend/src/apiserver/template/template.go:309-319 — setDefaultServiceAccount

backend/src/apiserver/template/argotemplate.go:60

backend/src/v2/template/v2template.go:152-153,393

backend/src/common/util/workflow.go:163-165

Framework: OWASP K8s K02; ASVS V4.1.3 CWE: CWE-269 (Improper Privilege Management) / CWE-441 (Confused Deputy) CVSS v3.1: 7.1 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N) – High

Exploitation POST /apis/v2beta1/runs with body {"experimentid":"...","pipelineversionreference":{...},"serviceaccount":"ds-pipeline-<dspa>"} (the API server's own SA). The user container then has that token mounted.

Impact A restricted tenant can run their container under a more-privileged SA simply by setting one field in the API call. Combined with the overprivileged pipeline-runner Role (secrets:get, pods/exec:, kubeflow.org /), a tenant can read every Secret in the namespace and exec into co-tenant pods. The DSP namespace also contains the ml-pipeline (apiserver), mariadb/minio, and operator-managed SAs.

Remediation Before setting serviceAccount, perform SAR {verb: "use", resource: "serviceaccounts", name: serviceAccount, namespace: ns} against the calling user. Or restrict to an allow-list configured by the operator (default pipeline-runner only).

First published (updated )
Severity
4

Kubernetes requires an authentication mechanism to enforce users’ privileges. One method of authentication, bearer tokens, are opaque strings used to associate a user with their having successfully authenticated previously. Any user with possession of this token may masquerade as the original user (the “bearer”) without further authentication.

Within Kubernetes, the bearer token is captured within the hyperkube kube-apiserver system logs at high verbosity levels (--v 10). A malicious user with access to the system logs on such a system could masquerade as any user who has previously logged into the system.

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