1. Executive summary
Atlantis, the pull-request automation server for Terraform, passes the 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 put shell metacharacters in the workspace name and run arbitrary commands as the Atlantis service account, without custom workflows, without allow_custom_workflows, and without apply permission. The command inherits the Atlantis process environment, which commonly holds cloud-provider, Terraform and VCS credentials, so the impact reaches beyond the Atlantis host. No CVE has been assigned in the advisory as published and no CVSS score, severity rating or CISA KEV entry is available for this item; the GitHub advisory is the only source and the assessment below rests on it alone. EMEA financial services firms running Atlantis against infrastructure repositories, particularly public repositories with --allow-fork-prs enabled, should treat any contributor able to open a plan-eligible pull request as able to reach the credentials the Atlantis process holds.
2. Regulatory framing
No specific DORA/NIS2 article is directly engaged by this item.
3. Technical analysis & attack chain
The flaw is a data-flow problem across four code locations in the Atlantis codebase, verified against upstream/main commit 92ce5c51d1a050357e44df3535483425e59fa984 on 13 August 2026. The workspace string is validated, then passed as a command argument, then joined into a single command string, then handed to a shell.
- The PR-controlled project workspace is validated in
server/core/config/raw/project.go(lines 139-149). Validation rejects only..,/and\. Shell metacharacters including;,#,$, redirections and whitespace pass validation.raw.Project.Validate()was confirmed to return no error for the proof-of-concept workspace value. - The workspace is passed directly as a Terraform command argument in
server/core/runtime/workspace_step_runner_delegate.go(lines 86-96) as[]string{workspaceCmd, "select", ctx.Workspace}. - Terraform arguments are concatenated into one string with
strings.Join(args, " ")inserver/core/terraform/tfclient/terraform_client.go(lines 451-468):tfCmd := fmt.Sprintf("%s %s", binPath, strings.Join(args, " ")). - The resulting string is executed through
sh -cin the same file (lines 416-427):cmd := exec.Command("sh", "-c", tfCmd).
A workspace value of poc;id;false;# therefore produces the equivalent of terraform workspace select poc;id;false;# and terraform workspace new poc;id;false;#. The injected false makes the first terraform workspace select fail, so Atlantis retries with terraform workspace new; the shell runs id as a separate command on both attempts. The second failure returns the combined command output in the Atlantis error response, which is how the proof of concept surfaces uid=1000(atlantis) gid=1000(atlantis) groups=1000(atlantis) back to the contributor. That reflected output is a useful detection signal: a failed plan whose error text contains command output the contributor did not ask Terraform to produce.
Preconditions are narrow and worth stating precisely. Atlantis must process atlantis.yaml from the pull request branch, and the pull request must be eligible to run atlantis plan. A fork pull request additionally requires the server to run with --allow-fork-prs; a same-repository branch does not. No custom workflow, no allow_custom_workflows setting and no apply permission are needed. The proof-of-concept repository uses a main.tf with required_version = ">= 1.0" and an atlantis.yaml at version 3 declaring a project named workspace-rce-poc with dir: ., the injected workspace value and autoplan disabled, triggered by the comment atlantis plan -p workspace-rce-poc.
The distinction from Atlantis's documented warning about planning untrusted Terraform matters. Atlantis already tells operators that providers and external data sources execute code during a plan. Here an ordinary project configuration field becomes shell source, which bypasses the explicit allow_custom_workflows control and needs no malicious provider, external data source, custom workflow or apply operation.
Post-exploitation reach follows the service account. The advisory lists reading and exfiltrating cloud-provider, Terraform and VCS credentials inherited from the Atlantis process; accessing Terraform state, plan files, repository checkouts and caches; modifying files or binaries the account can write; making network requests under the Atlantis server's network identity; and pivoting into infrastructure reachable through those credentials or that network placement. The proof of concept itself uses only id and false and does not touch credentials, make network requests or modify the host beyond Terraform possibly creating the disposable poc workspace. The credential-theft and pivot consequences are stated as potential impact, not as observed activity.
Exposure depends on repository model. For public repositories, arbitrary external contributors are directly exposed when --allow-fork-prs is enabled. Without fork PR support, the exposed population is anyone able to create an eligible same-repository pull request, plus an attacker who controls such an account.
The advisory names no affected or patched version range, and no fixed release is identified. The recommended remediation is to execute Terraform with an argument vector rather than shell source, for example exec.Command(binaryPath, args...), performing any required environment-variable expansion without invoking a shell. Strict workspace-name validation is offered as defence in depth, not as the primary fix.
The related Atlantis advisories in the corpus describe separate flaws and should not be conflated with this one. GHSA-26w5-6g95-gj28 covers path traversal in workspace handling for versions >= 0.19.8 and < 0.45.0, fixed in 0.45.0, where a workspace such as ../../../../../../../../tmp/f1-canary caused out-of-bounds directory creation and removal through os.RemoveAll and os.MkdirAll before Terraform rejected the name. GHSA-r4h6-8wpf-fw98 covers an unauthenticated /github-app/setup endpoint through 0.47.1 that exposes the GitHub App RSA private key and webhook secret. GHSA-gppm-hq3p-h4rp covers GitHub tokens (ghs_...) written to Atlantis logs during rotation, fixed in v0.30.0. They share a product and a theme of untrusted input reaching privileged operations, but each needs its own fix.
4. Mitigation & containment
P1 within 24h
- Inventory every Atlantis deployment and record whether it processes PR-controlled
atlantis.yaml, whether--allow-fork-prsis set, and which repositories can open plan-eligible pull requests. Public repositories with fork PRs enabled are the highest exposure. - Where fork PR support is not operationally required, disable
--allow-fork-prs. This removes the external-contributor path but not the same-repository path. - Restrict who can open plan-eligible pull requests on repositories Atlantis serves, and require review before any
atlantis.yamlchange merges. The injected value arrives in the PR branch, so branch protection on that file is a direct control. - Rotate the credentials in the Atlantis process environment: cloud-provider keys, Terraform Cloud or state backend tokens, and VCS tokens. Do this on the assumption that any deployment meeting the preconditions may already have been reached, because the flaw leaves no reliable trace beyond the reflected command output.
- Search Atlantis logs and PR comment history for plan failures whose error text contains shell output that Terraform would not produce, and for
atlantis.yamlworkspace values containing;,#,$, backticks,|,&or redirection characters.
P2 within 72h
- Apply the upstream fix once a patched release exists, or carry the code change: replace the
sh -cexecution inserver/core/terraform/tfclient/terraform_client.gowith an argument-vector call such asexec.Command(binaryPath, args...), and perform any environment-variable expansion without a shell. The advisory names no patched version, so track the GitHub advisory for the fixed release rather than assuming one. - Add strict workspace-name validation as defence in depth, permitting only the character set your projects actually use (letters, digits, hyphen, underscore). This is secondary to removing the shell.
- Run Atlantis with a dedicated service account holding the minimum cloud and VCS permissions its plans need, and scope its credentials per environment so a compromise of one Atlantis instance does not reach production infrastructure.
P3 within 7 days
- Move Atlantis credentials to short-lived, narrowly scoped tokens where the provider supports it, and remove standing organisation-admin rights from the Atlantis GitHub App.
- Review the separate Atlantis advisories in scope for your deployed version: path traversal in workspace handling (fixed in 0.45.0), the unauthenticated
/github-app/setupendpoint (through 0.47.1) and token logging (fixed in v0.30.0). Confirm your version against each.
5. Indicators of compromise
No indicators of compromise available in the source material. The advisory gives no hashes, domains, IP addresses or file paths belonging to an attacker. It does describe observable behaviour, set out below.
Behavioural indicators
| behaviour | where to observe | confidence |
|---|---|---|
atlantis.yaml project workspace value containing shell metacharacters (;, #, $, backticks, |, &, >, <) |
pull request diff, Atlantis plan logs | high, from the advisory's own proof of concept |
Plan failure whose error response contains shell command output (for example uid= and gid= from id) |
Atlantis error responses, PR comments, server logs | high |
terraform workspace select failing immediately followed by terraform workspace new with the same injected workspace string |
Atlantis server logs | medium, this retry is normal behaviour and only suspicious with a metacharacter-bearing workspace |
| Commands running as the Atlantis service account that were not invoked by a Terraform provider or data source | process auditing on the Atlantis host or container | medium |
6. Detection
The advisory supplies exact artefacts: the injected workspace string, the shell metacharacters that pass validation, and the terraform workspace select / terraform workspace new command shape. The YARA rule targets the proof-of-concept workspace string and the metacharacter pattern in atlantis.yaml content. The Sigma rule targets the process behaviour of a workspace argument carrying shell metacharacters.
rule Atlantis_Workspace_Command_Injection
{
meta:
author = "Adverse Trace"
date = "2026-10-28"
reference = "https://github.com/advisories/GHSA-rjh2-4xgw-p2hj"
description = "Detects atlantis.yaml content carrying shell metacharacters in the workspace field, as used in the Atlantis workspace command injection proof of concept"
strings:
$ws = "workspace:"
$poc = "poc;id;false;#"
$meta1 = ";id;"
$meta2 = ";false;#"
$meta3 = "$("
$meta4 = "`"
$meta5 = "&&"
$meta6 = "||"
condition:
$poc or ($ws and 2 of ($meta*))
}
title: Atlantis Terraform workspace argument with shell metacharacters
id: 7f3c2a91-4b6e-4d18-9c2a-atlantis-ws-inject
status: experimental
description: Detects a terraform workspace select or new invocation whose workspace argument contains shell metacharacters, consistent with the Atlantis workspace command injection
references:
- https://github.com/advisories/GHSA-rjh2-4xgw-p2hj
author: Adverse Trace
date: 2026-10-28
logsource:
category: process_creation
product: linux
detection:
selection_img:
Image|endswith:
- '/terraform'
selection_cmd:
CommandLine|contains:
- 'workspace select'
- 'workspace new'
selection_meta:
CommandLine|contains:
- ';'
- '#'
- '$('
- '`'
- '&&'
- '||'
condition: selection_img and selection_cmd and selection_meta
falsepositives:
- Legitimate workspace names containing characters outside letters, digits, hyphen and underscore, which Atlantis validation permits
level: high
7. Sources
- GitHub Security Advisories, "Atlantis: OS command injection through PR-controlled Terraform workspace enables RCE during plan" (GHSA-rjh2-4xgw-p2hj), https://github.com/advisories/GHSA-rjh2-4xgw-p2hj, published 2026-10-27.
- GitHub Security Advisories, "Atlantis Workspace Handling has Path Traversal that Allows Out-of-Bounds Directory Deletion/Creation" (GHSA-26w5-6g95-gj28), https://github.com/advisories/GHSA-26w5-6g95-gj28.
- GitHub Security Advisories, "Atlantis through 0.47.1 fails to authenticate the /github-app/setup endpoint" (GHSA-r4h6-8wpf-fw98), https://github.com/advisories/GHSA-r4h6-8wpf-fw98.
- GitHub Security Advisories, "Git credentials are exposed in Atlantis logs" (GHSA-gppm-hq3p-h4rp), https://github.com/advisories/GHSA-gppm-hq3p-h4rp.
8. Adverse Trace position
Adverse Trace assesses this as a high-impact configuration-to-code-execution flaw in a component that by design holds privileged cloud and VCS credentials, but the assessment is single-sourced: the GitHub advisory is the only source, no CVE has been assigned in it, and no CVSS score, severity rating or CISA KEV entry is available, so we do not assign a numeric severity here. The exposure is real for any firm running Atlantis against infrastructure repositories with fork PRs enabled or with a broad set of same-repository contributors, because the only precondition is a plan-eligible pull request and the reward is the credential set the Atlantis process holds. We will track the advisory for a patched release and a CVE identifier, and we will reissue this note when either appears. Clients should confirm their Atlantis version and --allow-fork-prs setting and report back so we can scope the credential rotation.
Published via PulseTrace — Adverse Trace threat intelligence.