GHSA-mmg6-4qmv-6pc8: Path Traversal
Impact
Path traversal via link following in the Infracost config-template parser. The readFile, pathExists, isDir, and matchPaths template functions confined repo-supplied paths with a lexical filepath.Rel check plus a leaf-only os.Lstat:
{{ readFile "evil/file" }}
With an intermediate directory symlink committed in the repo (evil -> /), the path is lexically clean and the leaf is a regular file, so both checks pass, but os.ReadFile follows the symlink and reads outside the checkout. The contents are rendered into the generated config and surfaced via the Infracost dashboard and PR comment, so anyone who can open a pull request can read files off the runner.
Affects infracost up to and including v0.10.44. Successful exploitation reads any file the CLI process can reach on the runner. Impact depends on what the run exposes: under on: pullrequest (the configuration in Infracost's documentation) fork pull requests run without secrets and with a read-only token, so exposure is limited. If Infracost runs under pullrequesttarget, or is triggered by a same-repository pull request, the read reaches the repository's secrets, enabling secret theft. The patch confines all four functions regardless of trigger.
Patches
Fixed in v0.10.45 (#3586) by routing all four functions through security.IsPathAllowed, which resolves symlinks anywhere in the path before a segment-aware containment check. The same fix landed in config#14 and parser#144. - Installed via the official script, a package manager, or the latest Docker tag: upgrade to v0.10.45 (or later) to receive the fix. - Pinned to a specific version or image digest: bump to v0.10.45.
Workarounds
No full fix without upgrading. To limit exposure: run Infracost under on: pullrequest rather than pullrequesttarget, and keep fork pull requests from receiving secrets (the defaults).
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
go/github.com/infracost/infracostto a version that resolves this vulnerability.Fixed in 0.10.45 - Upgrade
Upgrade
infracostto a version that resolves this vulnerability.Fixed in v0.10.45 - Compensating control
Configure the GitHub workflow to run Infracost under `on: pull_request` (not `pull_request_target`) so fork pull requests run without secrets and with a read-only token.
Event History
Frequently Asked Questions
Which CI workflows are most exposed to secret theft?
Workflows that run Infracost under pull_request_target or on same-repository pull requests are most exposed, because the vulnerable CLI can read repository secrets available to the runner. Under the documented pull_request configuration, fork pull requests have no secrets and only a read-only token, which limits the exposure.
What must an attacker be able to do to exploit this?
The attacker needs to be able to open a pull request containing a repository-controlled intermediate directory symlink and a config template that invokes one of the affected file-related template functions. The vulnerable run must process that pull request with Infracost.
How can we tell whether a workflow is affected?
Check whether it uses infracost v0.10.44 or earlier and whether repository-supplied config templates can call readFile, pathExists, isDir, or matchPaths. Also review the workflow trigger and runner permissions to determine what files or secrets the CLI process could read.
What can be done if updating is not immediately possible?
Avoid running vulnerable Infracost versions on untrusted pull-request content where the runner can access secrets or sensitive files. In particular, do not use pull_request_target for such runs, and restrict Infracost execution to contexts without secrets until it can be updated.