Skip to content

Adopt zizmor for static analysis of GitHub Actions workflows #76

Description

@michaelpeterswa

Summary

Zizmor is a static analysis tool. Zizmor examines GitHub Actions workflows. Zizmor finds security problems and correctness problems in workflows.

This repo publishes workflow templates. Many repos in the organization use these templates: go_app_*, go_lib_*, php_lib_*, ruby_app_*, and gradle_*. If we fix a problem in this repo, every repo that uses the template gets the fix. The other repos do not need to do any work.

We propose to adopt zizmor in this repo.

Why now

We ran zizmor version 1.29.0 against the Go workflow templates. We scanned 5 files: go_app_pull_requests.yml, go_app_push_main.yml, go_app_release.yml, go_lib_pull_requests.yml, and go_lib_push_main.yml. The scan found 115 problems.

Rule Count Severity What the problem is
unpinned-uses 62 High The workflow refers to an action by a tag, for example @v4. A tag can change. If the tag changes, the workflow runs different code without warning.
template-injection 24 High/Med The workflow inserts a value directly into a shell command. An attacker may control this value. This can let an attacker inject code into the shell command.
artipacked 16 Low/Med The checkout step keeps the GITHUB_TOKEN credential in the local git config. A later step can read this credential and send it outside the workflow.
ref-confusion 8 Medium The workflow refers to an action with a ref like @v1. GitHub cannot tell if this ref is a branch or a tag.
adhoc-packages 4 Low The workflow installs packages with npm install and no lock file. The install is not reproducible.
cache-poisoning 1 High The setup-go action caches files by default. The same job also builds and pushes a Docker image. An attacker may poison the cache. The poisoned cache may reach the published image.

Across all templates (Go, PHP, Ruby, and Gradle), the scan found 212 problems. The scan also found one known vulnerability, in gradle/gradle-build-action@v1 (GHSA-h3qr-39j9-4r5v). The scan found 3 uses of an archived action. Nobody maintains an archived action.

These templates are reusable workflows. Teams that call these templates cannot see these problems. The teams trust us to secure the templates.

Proposed benefits

  • We fix each problem one time. Every repo that uses the template gets the fix. Teams do not need to open a pull request.
  • We pin each action to a commit hash. Dependabot updates the hash later. This stops an attacker from changing a tag and changing our workflow without our knowledge.
  • We move values out of shell commands. We put the values into environment variables instead. This removes a path for code injection.
  • We add zizmor as a permanent check in this repo. If a future change adds a new problem, the check finds the problem during review.
  • Zizmor fixes most problems automatically. The --fix command handles the majority of the 115 findings. We must fix the remaining problems by hand: a few ad-hoc package installs, and the Gradle action.
  • This adoption costs nothing today. This repo is public. GitHub code scanning is free for public repos. We do not need a GitHub Advanced Security license for this repo.

Proposed plan

  1. Add a zizmor check to this repo. Upload the results to GitHub code scanning.
  2. Run zizmor --fix=all on the Go workflow templates. Review each change by hand. Fix the ad-hoc package problems by hand. Publish a new minor version tag.
  3. Add a Dependabot configuration for GitHub Actions. This keeps the new commit hashes up to date.
  4. Later: publish a reusable zizmor_scan.yml workflow. Private repos can call this workflow directly. Use the github annotation format by default, because most private repos do not have GitHub Advanced Security.
  5. Later: clean up the PHP, Ruby, and Gradle templates. Replace gradle/gradle-build-action, because this action is archived and has a known vulnerability.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions