Files
ruff/.github
Alex Waygood 58e7db89a1 Run zizmor in CI, and fix most warnings (#14844)
## Summary

A [recent exploit](https://github.com/advisories/GHSA-7x29-qqmq-v6qc)
brought attention to how easy it can be for attackers to use template
expansion in GitHub Actions workflows to inject arbitrary code into a
repository. That vulnerability [would have been caught by the zizmor
linter](https://blog.yossarian.net/2024/12/06/zizmor-ultralytics-injection),
which looks for potential security vulnerabilities in GitHub Actions
workflows. This PR adds [zizmor](https://github.com/woodruffw/zizmor) as
a pre-commit hook and fixes the high- and medium-severity warnings
flagged by the tool.

All the warnings fixed in this PR are related to this zizmor check:
https://woodruffw.github.io/zizmor/audits/#artipacked. The summary of
the check is that `actions/checkout` will by default persist git
configuration for the duration of the workflow, which can be insecure.
It's unnecessary unless you actually need to do things with `git` later
on in the workflow. None of our workflows do except for
`publish-docs.yml` and `sync-typeshed.yml`, so I set
`persist-credentials: true` for those two but `persist-credentials:
false` for all other uses of `actions/checkout`.

Unfortunately there are several warnings in `release.yml`, including
four high-severity warnings. However, this is a generated workflow file,
so I have deliberately excluded this file from the check. These are the
findings in `release.yml`:

<details>
<summary>release.yml findings</summary>

```
warning[artipacked]: credential persistence through GitHub Actions artifacts
  --> /Users/alexw/dev/ruff/.github/workflows/release.yml:62:9
   |
62 |         - uses: actions/checkout@v4
   |  _________-
63 | |         with:
64 | |           submodules: recursive
   | |_______________________________- does not set persist-credentials: false
   |
   = note: audit confidence → Low

warning[artipacked]: credential persistence through GitHub Actions artifacts
   --> /Users/alexw/dev/ruff/.github/workflows/release.yml:124:9
    |
124 |         - uses: actions/checkout@v4
    |  _________-
125 | |         with:
126 | |           submodules: recursive
    | |_______________________________- does not set persist-credentials: false
    |
    = note: audit confidence → Low

warning[artipacked]: credential persistence through GitHub Actions artifacts
   --> /Users/alexw/dev/ruff/.github/workflows/release.yml:174:9
    |
174 |         - uses: actions/checkout@v4
    |  _________-
175 | |         with:
176 | |           submodules: recursive
    | |_______________________________- does not set persist-credentials: false
    |
    = note: audit confidence → Low

warning[artipacked]: credential persistence through GitHub Actions artifacts
   --> /Users/alexw/dev/ruff/.github/workflows/release.yml:249:9
    |
249 |         - uses: actions/checkout@v4
    |  _________-
250 | |         with:
251 | |           submodules: recursive
252 | |       # Create a GitHub Release while uploading all files to it
    | |_______________________________________________________________- does not set persist-credentials: false
    |
    = note: audit confidence → Low

error[excessive-permissions]: overly broad workflow or job-level permissions
  --> /Users/alexw/dev/ruff/.github/workflows/release.yml:17:1
   |
17 | / permissions:
18 | |   "contents": "write"
...  |
39 | | # If there's a prerelease-style suffix to the version, then the release(s)
40 | | # will be marked as a prerelease.
   | |_________________________________^ contents: write is overly broad at the workflow level
   |
   = note: audit confidence → High

error[template-injection]: code injection via template expansion
  --> /Users/alexw/dev/ruff/.github/workflows/release.yml:80:9
   |
80 |          - id: plan
   |   _________^
81 |  |         run: |
   |  |_________^
82 | ||           dist ${{ (inputs.tag && inputs.tag != 'dry-run' && format('host --steps=create --tag={0}', inputs.tag)) || 'plan' }} --out...
83 | ||           echo "dist ran successfully"
84 | ||           cat plan-dist-manifest.json
85 | ||           echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
   | ||__________________________________________________________________________________^ this step
   | ||__________________________________________________________________________________^ inputs.tag may expand into attacker-controllable code
   |
   = note: audit confidence → Low

error[template-injection]: code injection via template expansion
  --> /Users/alexw/dev/ruff/.github/workflows/release.yml:80:9
   |
80 |          - id: plan
   |   _________^
81 |  |         run: |
   |  |_________^
82 | ||           dist ${{ (inputs.tag && inputs.tag != 'dry-run' && format('host --steps=create --tag={0}', inputs.tag)) || 'plan' }} --out...
83 | ||           echo "dist ran successfully"
84 | ||           cat plan-dist-manifest.json
85 | ||           echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
   | ||__________________________________________________________________________________^ this step
   | ||__________________________________________________________________________________^ inputs.tag may expand into attacker-controllable code
   |
   = note: audit confidence → Low

error[template-injection]: code injection via template expansion
  --> /Users/alexw/dev/ruff/.github/workflows/release.yml:80:9
   |
80 |          - id: plan
   |   _________^
81 |  |         run: |
   |  |_________^
82 | ||           dist ${{ (inputs.tag && inputs.tag != 'dry-run' && format('host --steps=create --tag={0}', inputs.tag)) || 'plan' }} --out...
83 | ||           echo "dist ran successfully"
84 | ||           cat plan-dist-manifest.json
85 | ||           echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
   | ||__________________________________________________________________________________^ this step
   | ||__________________________________________________________________________________^ inputs.tag may expand into attacker-controllable code
   |
   = note: audit confidence → Low
```

</details>

## Test Plan

`uvx pre-commit run -a`
2024-12-09 00:42:06 +00:00
..