ECLI-003: Buildkite bootstraps executable tools without repository-controlled integrity verification
- Dominant language
- TypeScript
- Stars
- 41
- Forks
- 24
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 56
Description
**Severity: Medium**
### Problem
The `pre-command` hook downloads the nvm installer from GitHub and pipes it directly to `bash`:
- [.buildkite/hooks/pre-command:19](https://github.com/elastic/cli/blob/main/.buildkite/hooks/pre-command#L19)
Although the URL pins the `v0.39.7` tag, Git tags are mutable and can be moved or replaced. The downloaded content is not verified against a repository-controlled digest. Because `nvm.sh` is sourced into the current shell, a compromised installer could intercept the later `vault` invocation or access the agent's ambient Vault identity.
Three test scripts contain fallback nvm installers that fetch the current GitHub release without version pinning or integrity verification: [run-cloud-tests.sh:15](https://github.com/elastic/cli/blob/main/.buildkite/run-cloud-tests.sh#L15), [run-es-tests.sh:29](https://github.com/elastic/cli/blob/main/.buildkite/run-es-tests.sh#L29), [run-kb-tests.sh:110](https://github.com/elastic/cli/blob/main/.buildkite/run-kb-tests.sh#L110). The ES and Kibana scripts also download unverified `jq` binaries: [run-es-tests.sh:42](https://github.com/elastic/cli/blob/main/.buildkite/run-es-tests.sh#L42), [run-kb-tests.sh:123](https://github.com/elastic/cli/blob/main/.buildkite/run-kb-tests.sh#L123). See also ECLI-014 for whether PR builds receive a Vault-capable agent identity.
### Fix
- Remove the duplicate nvm installation blocks from the test scripts and rely
on one hardened bootstrap implementation.
- Pin the nvm installer to an immutable commit SHA rather than a mutable tag.
- Download to a temporary file, verify it against a SHA-256 value **committed
to this repository**, then execute. Do not pipe directly to `bash`.
Downloading the checksum from the same GitHub release is insufficient against
a compromised release — the expected hash must come from the repository or be
cryptographically signed by a separately trusted key.
- Apply the same pattern to `jq`: pin by version and platform, store the
expected SHA-256 in the repository, verify before installing, fail closed on
mismatch.
- Restrict the Cloud Vault policy to the Cloud test job and ensure PR builds
cannot receive a Vault-capable agent identity (see ECLI-014).
### Risk
**Medium** (low exploitability, high impact). Raise to **High** if PR builds use Vault-authorized agents or the credentials can affect production.
---
Copied from the [security review](https://github.com/elastic/infosec/issues/27626#issuecomment-5172341916) in elastic/infosec#27626 (ECLI-003).
Contributor guide
Assessment
This issue has not been assessed yet.