LukeMathWalker / LukeMathWalker/cargo-chef
Harden CI workflows against script injection and credential exposure
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 2.7k
- Forks
- 146
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
Pinning actions to SHAs (see [#361](https://github.com/LukeMathWalker/cargo-chef/issues/361)) removes one CI attack surface, but it does not address vulnerabilities inside the workflow definitions themselves.
The workflows in this repository contain a few well-known GitHub Actions anti-patterns that an attacker could abuse:
- **Template injection:** GitHub `${{ ... }}` expressions are expanded *before* the shell runs, so any expression interpolated directly into a `run:` block is substituted as raw text into the script. Values that an attacker can influence (matrix entries, step outputs, `cargo-dist` install commands, anything derived from a pull request) can therefore break out of the intended command and execute arbitrary shell with access to repository secrets and the `GITHUB_TOKEN`.
- **Credential persistence:** `actions/checkout` writes the `GITHUB_TOKEN` into `.git/config` by default (`persist-credentials: true`). Every later step - including any third-party action - can read that token and reuse it. This is called an [ArtiPACKED Vulnerability](https://thehackernews.com/2024/08/github-vulnerability-artipacked-exposes.html).
- **Excessive permissions:** the release workflow grants `contents: write` at the top level, so every job runs with write access even though only a couple of jobs actually need it.
- **Unpinned container images:** a job pulls a container image from a dynamic matrix, which cannot be expressed as a static SHA pin and needs an explicit, documented exception.
`cargo-chef` produces the DockerHub image and the released binaries that downstream build pipelines depend on. A compromise of these workflows would let an attacker tamper with those build artifacts. This supply-chain risk needs to be ruled out by security-aware users before adopting `cargo-chef`.
## Why static analysis (zizmor) fixes this
[`zizmor`](https://docs.zizmor.sh/) is a static analysis tool for GitHub Actions workflows. It detects template injection, credential persistence, over-broad permissions, unpinned images, and related findings, and many of them can be auto-corrected with `zizmor --fix`.
The fixes follow GitHub's own hardening guidance:
- The template-injection fixes use the recommended pattern of passing the expression through an [intermediate environment variable](https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks) instead of interpolating it into the script body. This is the section `zizmor --fix` partly automated.
- The permission tightening follows ["Restricting permissions for tokens"](https://docs.github.com/en/actions/reference/security/secure-use#restricting-permissions-for-tokens), defaulting the workflow to `contents: read` and granting `contents: write` only to the jobs that publish.
## Proposed change
- Run `zizmor` as a dedicated CI job so new workflow changes are checked automatically.
- Apply `zizmor --fix` and the matching manual fixes:
- move `${{ ... }}` expressions out of `run:` blocks and into `env:` variables that are referenced as quoted shell variables,
- set `persist-credentials: false` on every `actions/checkout`,
- default the release workflow to `contents: read` and escalate to `contents: write` per job,
- document the one unavoidable `unpinned-images` finding with an inline `zizmor: ignore` and a justification.
## References
- GitHub Docs - [Good practices for mitigating script injection attacks](https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks)
- GitHub Docs - [Restricting permissions for tokens](https://docs.github.com/en/actions/reference/security/secure-use#restricting-permissions-for-tokens)
- GitHub Docs - [Using third-party actions](https://docs.github.com/en/actions/reference/security/secure-use#using-third-party-actions)
- zizmor - [documentation](https://docs.zizmor.sh/)
- [`zizmorcore/zizmor-action`](https://github.com/zizmorcore/zizmor-action)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Inspect the repository's GitHub Actions workflow definitions, especially the release workflow, and run zizmor to establish the current findings. Apply the proposed hardening across the workflows, add the dedicated zizmor CI check, and verify that only the documented dynamic image remains ignored and required release permissions still work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, github-actions
- Domain
- ci-cd, devops, security
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100