Audit Rules🔗
This page documents each of the audits currently implemented in zizmor
.
See each audit's section for its scope, behavior, and other information.
artipacked
🔗
Type | Examples | Introduced in |
---|---|---|
Workflow | artipacked.yml | v0.1.0 |
What🔗
Unexpected credential use and potential credential persistence, typically via GitHub Actions artifact creation or action logs.
Why🔗
The default checkout action is [actions/checkout
].
By default, using actions/checkout
causes a credential to be persisted
in the checked-out repo's .git/config
, so that subsequent git
operations
can be authenticated.
Subsequent steps may accidentally publicly persist .git/config
, e.g. by
including it in a publicly accessible artifact via [actions/upload-artifact
].
However, even without this, persisting the credential in the .git/config
is non-ideal and should be disabled with persist-credentials: false
unless
the job actually needs the persisted credential.
Other resources🔗
dangerous-triggers
🔗
Type | Examples | Introduced in |
---|---|---|
Workflow | pull-request-target.yml | v0.1.0 |
What🔗
Fundamentally dangerous GitHub Actions workflow triggers.
Why🔗
Many of GitHub's workflow triggers are difficult to use securely. This audit checks for some of the biggest offenders:
pull_request_target
workflow_run
These triggers are dangerous because they run in the context of the target repository rather than the fork repository, while also being typically triggerable by the latter. This can lead to attacker controlled code execution or unexpected action runs with context controlled by a malicious fork.
Other resources🔗
excessive-permissions
🔗
Type | Examples | Introduced in |
---|---|---|
Workflow | excessive-permissions.yml | v0.1.0 |
What🔗
Looks for excessive permissions in workflows, both at the workflow level and individual job levels.
Why🔗
Users frequently over-scope their workflow and job permissions, or set broad workflow-level permissions without realizing that all jobs inherit those permissions.
hardcoded-container-credentials
🔗
Type | Examples | Introduced in |
---|---|---|
Workflow | hardcoded-credentials.yml | v0.1.0 |
What🔗
GitHub Actions allows Docker credentials (usernames and passwords) to be hardcoded in various places within workflows.
Why🔗
Hardcoding credentials is bad.
impostor-commit
🔗
Type | Examples | Introduced in |
---|---|---|
Workflow | impostor-commit.yml | v0.1.0 |
What🔗
GitHub represents a repository and its forks as a "network" of commits.
This results in ambiguity about where a commit comes from: a commit
that exists only in a fork can be referenced via its parent's
owner/repo
slug, and vice versa.
Why🔗
GitHub's network-of-forks design can be used to obscure a commit's true origin
in a fully-pinned uses:
workflow reference. This can be used by an attacker
to surreptitiously introduce a backdoored action into a victim's workflows(s).
Other resources🔗
known-vulnerable-actions
🔗
Type | Examples | Introduced in |
---|---|---|
Workflow | known-vulnerable-actions.yml | v0.1.0 |
What🔗
Actions with known, publicly disclosed vulnerabilities are tracked in the GitHub Advisories database. Examples of commonly disclosed vulnerabilities in GitHub Actions include credential disclosure and code injection via template injection.
Why🔗
You shouldn't use actions with known vulnerabilities.
ref-confusion
🔗
Type | Examples | Introduced in |
---|---|---|
Workflow | ref-confusion.yml | v0.1.0 |
What🔗
Like with impostor commits, actions that are used with a symbolic ref
in their uses:
are subject to a degree of ambiguity: a ref like
@v1
might refer to either a branch or tag ref.
Why🔗
An attacker can exploit this ambiguity to publish a branch or tag ref that takes precedence over a legitimate one, delivering a malicious action to pre-existing consumers of that action without having to modify those consumers.
self-hosted-runner
🔗
Type | Examples | Introduced in |
---|---|---|
Workflow | self-hosted.yml | v0.1.0 |
What🔗
GitHub supports self-hosted runners, which behave similarly to GitHub-hosted runners but use client-managed compute resources.
Why🔗
Self-hosted runners are very hard to secure by default, which is why GitHub does not recommend their use in public repositories.
Other resources🔗
template-injection
🔗
Type | Examples | Introduced in |
---|---|---|
Workflow | template-injection.yml | v0.1.0 |
What🔗
GitHub Actions allows workflows to define template expansions, which
occur within special ${{ ... }}
delimiters. These expansions happen
before workflow and job execution, meaning the expansion
of a given expression appears verbatim in whatever context it was performed in.
Why🔗
Template expansions aren't syntax-aware, meaning that they can result in
unintended shell injection vectors. This is especially true when they're
used with attacker-controllable expression contexts, such as
github.event.issue.title
(which the attacker can fully control by supplying
a new issue title).
Other resources🔗
use-trusted-publishing
🔗
Type | Examples | Introduced in |
---|---|---|
Workflow | pypi-manual-credential.yml | v0.1.0 |
What🔗
Some packaging ecosystems/indices (like PyPI and RubyGems) support "Trusted Publishing," which is an OIDC-based "tokenless" authentication mechanism for uploading to the index from within a CI/CD workflow.
Why🔗
This "tokenless" flow has significant security benefits over a traditional manually configured API token, and should be preferred wherever supported and possible.