CVE-2026-116676
Atlantis: OS command injection through PR-controlled Terraform workspace enables RCE during plan
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.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.8
Atlantis: OS command injection through PR-controlled Terraform workspace enables RCE during plan
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.
- Record
CVE-2026-116676- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-03
EUVDEUVD-2026-111231
8.8
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.
- Record
EUVD-2026-111231- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-03
GitHub AdvisoriesGHSA-rjh2-4xgw-p2hj
8.8
Atlantis: OS command injection through PR-controlled Terraform workspace enables RCE during plan
Summary
Atlantis passes the Terraform workspace value from a pull request's atlantis.yaml into a shell command without quoting or escaping it.
A 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.
The executed command inherits the Atlantis process environment, which commonly contains cloud-provider, Terraform, and VCS credentials.
Details
Verified against current upstream/main commit 92ce5c51d1a050357e44df3535483425e59fa984 on August 13, 2026.
The vulnerable data flow is:
-
The PR-controlled project workspace is validated in
server/core/config/raw/project.go.Validation rejects only
..,/, and\. Shell metacharacters such as;,#,$, redirections, and whitespace remain permitted. -
The workspace is passed directly as a Terraform command argument in
server/core/runtime/workspace_step_runner_delegate.go:[]string{workspaceCmd, "select", ctx.Workspace} -
Terraform arguments are concatenated into a single string using
strings.Join(args, " ")inserver/core/terraform/tfclient/terraform_client.go:tfCmd := fmt.Sprintf("%s %s", binPath, strings.Join(args, " ")) -
The resulting string is executed through
sh -cinserver/core/terraform/tfclient/terraform_client.go:cmd := exec.Command("sh", "-c", tfCmd)
Consequently, a workspace such as:
poc;id;false;#
produces commands equivalent to:
terraform workspace select poc;id;false;#
terraform workspace new poc;id;false;#
raw.Project.Validate() was confirmed to return no error for this workspace value.
Atlantis 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.
The 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.
PoC
Only reproduce this against a disposable Atlantis instance and test repository.
Preconditions
- Atlantis processes
atlantis.yamlfrom the pull request branch. - The pull request is eligible to run
atlantis plan. - For a fork pull request, the server must have
--allow-fork-prsenabled. A same-repository branch does not require this flag. - No custom workflows or apply permissions are required.
Repository contents
Create main.tf:
terraform {
required_version = ">= 1.0"
}
Create atlantis.yaml:
version: 3
projects:
- name: workspace-rce-poc
dir: .
workspace: "poc;id;false;#"
autoplan:
enabled: false
Open a pull request containing these files and comment:
atlantis plan -p workspace-rce-poc
Expected result
Atlantis first runs `terraform workspace…
- Record
GHSA-rjh2-4xgw-p2hj- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
NVD
8.8
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.
- Record
CVE-2026-116676- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-03
OSV
8.8
Atlantis: OS command injection through PR-controlled Terraform workspace enables RCE during plan
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.
- Record
CVE-2026-116676- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-06
OSVGHSA-rjh2-4xgw-p2hj
8.8
Atlantis: OS command injection through PR-controlled Terraform workspace enables RCE during plan
Summary
Atlantis passes the Terraform workspace value from a pull request's atlantis.yaml into a shell command without quoting or escaping it.
A 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.
The executed command inherits the Atlantis process environment, which commonly contains cloud-provider, Terraform, and VCS credentials.
Details
Verified against current upstream/main commit 92ce5c51d1a050357e44df3535483425e59fa984 on August 13, 2026.
The vulnerable data flow is:
-
The PR-controlled project workspace is validated in
server/core/config/raw/project.go.Validation rejects only
..,/, and\. Shell metacharacters such as;,#,$, redirections, and whitespace remain permitted. -
The workspace is passed directly as a Terraform command argument in
server/core/runtime/workspace_step_runner_delegate.go:[]string{workspaceCmd, "select", ctx.Workspace} -
Terraform arguments are concatenated into a single string using
strings.Join(args, " ")inserver/core/terraform/tfclient/terraform_client.go:tfCmd := fmt.Sprintf("%s %s", binPath, strings.Join(args, " ")) -
The resulting string is executed through
sh -cinserver/core/terraform/tfclient/terraform_client.go:cmd := exec.Command("sh", "-c", tfCmd)
Consequently, a workspace such as:
poc;id;false;#
produces commands equivalent to:
terraform workspace select poc;id;false;#
terraform workspace new poc;id;false;#
raw.Project.Validate() was confirmed to return no error for this workspace value.
Atlantis 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.
The 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.
PoC
Only reproduce this against a disposable Atlantis instance and test repository.
Preconditions
- Atlantis processes
atlantis.yamlfrom the pull request branch. - The pull request is eligible to run
atlantis plan. - For a fork pull request, the server must have
--allow-fork-prsenabled. A same-repository branch does not require this flag. - No custom workflows or apply permissions are required.
Repository contents
Create main.tf:
terraform {
required_version = ">= 1.0"
}
Create atlantis.yaml:
version: 3
projects:
- name: workspace-rce-poc
dir: .
workspace: "poc;id;false;#"
autoplan:
enabled: false
Open a pull request containing these files and comment:
atlantis plan -p workspace-rce-poc
Expected result
Atlantis first runs `terraform workspace…
- Record
GHSA-rjh2-4xgw-p2hj- CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-06
OSVGO-2026-6871 No score
OS command injection through PR-controlled Terraform workspace enables RCE during plan in github.com/runatlantis/atlantis
OS command injection through PR-controlled Terraform workspace enables RCE during plan in github.com/runatlantis/atlantis
- Record
GO-2026-6871- Updated
- 2026-11-06
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/runatlantis/atlantisGo |
0.4.0 to 0.47.0 | 0.47.1 |
github.com/runatlantis/atlantisGo |
0.4.0 up to 0.47.1 | 0.47.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases | OSV | |
| facts | EUVD, NVD | |
| references | CVE List | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-116676 is a high vulnerability (CVSS 8.8) in Runatlantis Atlantis, published October 27, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.47%, the 40th percentile. Fixed in github.com/runatlantis/atlantis 0.47.1.
References
github.com/runatlantis/atlantis/security/advisories/GHSA-rjh2-4xgw-p2hj
github.com/runatlantis/atlantis/pull/6792
github.com/runatlantis/atlantis/commit/8dd22b4d0a9d7c129fdbf6a3398dd1c4cf8c3a59
github.com/runatlantis/atlantis/commit/f04df0d53f0544d9eb6f5026dd8b74fbefd82ac8
github.com/runatlantis/atlantis/releases/tag/v0.47.1
nvd.nist.gov/vuln/detail/CVE-2026-116676
github.com/advisories/GHSA-rjh2-4xgw-p2hj
github.com/CVEProject/cvelistV5/tree/main/cves/2026/116xxx/CVE-2026-116676.json
github.com/runatlantis/atlantis
Left out here: the rest of 2 source descriptions. The JSON record has them.