hashicorp / hashicorp/setup-terraform

Verify downloaded Terraform zip against published SHA256SUMS / SHA256SUMS.sig

Open
#556 3 comments 2 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
1.6k
Forks
288
Avg merge
23h 21m
Merged PRs (30d)
3

Description

Hi! This is a security-hygiene request from a downstream consumer — the Apache Software Foundation's [allowlist of approved GitHub Actions](https://github.com/apache/infrastructure-actions).

`setup-terraform` currently downloads the Terraform release zip and extracts it without verifying its integrity:

https://github.com/hashicorp/setup-terraform/blob/dfe3c3f87815947d99a8997f908cb6525fc44e9e/lib/setup-terraform.js#L37-L62

```js
async function downloadCLI (url) {
core.debug(`Downloading Terraform CLI from ${url}`);
const pathToCLIZip = await tc.downloadTool(url);
...
pathToCLI = await tc.extractZip(pathToCLIZip);
...
}
```

TLS protects the bytes in transit from `releases.hashicorp.com`, but the action takes no defense-in-depth step beyond that — a compromised mirror, CDN incident, or any future change to the resolved URL would land an arbitrary binary on every runner that uses the action.

HashiCorp already publishes everything needed to close that gap at each release:

- `terraform__SHA256SUMS` — SHA256 of every release asset
- `terraform__SHA256SUMS..sig` — detached PGP signature over the sums file, signed with the [HashiCorp release GPG key](https://www.hashicorp.com/security)

### Proposed fix

A minimal fix inside `downloadCLI`:

1. After `tc.downloadTool(url)` returns the zip path, also fetch `terraform__SHA256SUMS` for the same release.
2. Find the line for the platform-specific zip filename.
3. Hash the downloaded zip with Node's `crypto.createHash('sha256')` and compare; fail loudly if it doesn't match.

A stronger fix additionally verifies `SHA256SUMS.sig` against the HashiCorp public key — `@hashicorp/js-releases` already knows about the release index, so the signature path is a natural extension.

### Downstream impact

The ASF reviews every new commit hash of every action it adds to its allowlist. Our verification script flags every release of `setup-terraform` because of this missing check — most recently on the v4.0.0 → v4.0.1 bump in [apache/infrastructure-actions#836](https://github.com/apache/infrastructure-actions/pull/836). We're approving 836 because the download shape didn't change between v4.0.0 (already approved) and v4.0.1, but every future bump will need a manual security re-review until the action verifies what it downloads.

Happy to send a PR if it'd help.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in lib/setup-terraform.js at downloadCLI, especially the downloadTool and extractZip flow around lines 37-62. Review how @hashicorp/js-releases exposes release assets, then trace the existing tests and release handling before changing behavior. Done means the platform-specific zip is checked against the matching SHA256SUMS entry and mismatches fail clearly; detached signature verification is the stronger scope described in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
github-actions, javascript, node.js
Domain
devops, security
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.