Coverage area · 2 checks
CI/CD pipeline security for GitHub Actions
Your pipeline holds the keys to production: deploy credentials, registry tokens, signing keys. OpenRouting reviews workflow files for the patterns that let untrusted code or text reach those secrets.
Illustrative example of how a finding in this area is reviewed.
Why this area matters
Build systems are a prime supply-chain target because one compromised pipeline can ship malicious code to every user. The common workflow mistakes are well documented by GitHub's own security guidance: expanding untrusted event text into shell scripts, running fork code with secrets under pull_request_target, granting the job token write access to everything, and referencing third-party actions by a movable tag.
IaC scanners catch some of these, but the risk depends on context — which event triggers the workflow, whether a step checks out untrusted code, and what the token can do. The CI/CD agent reads the whole workflow before deciding.
What goes wrong in real applications
Script injection from event data
Expanding PR titles, branch names or issue bodies directly inside run: steps lets anyone who opens a PR or issue inject shell commands into your build.
Secrets exposed to untrusted code
pull_request_target and similar triggers run with repository secrets; checking out and running the fork's code there hands those secrets to the PR author.
Over-scoped job tokens
permissions: write-all, or no permissions block on older defaults, lets any compromised step push code, create releases or modify settings.
Mutable action references
Third-party actions pinned to a branch or tag run whatever the owner pushes next, including a compromised version.
Sample: the risky pattern and the fix
on: pull_request_target
permissions: write-all
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- run: echo "Triaging: ${{ github.event.pull_request.title }}"
- uses: some-org/label-action@mainon: pull_request
permissions:
contents: read
pull-requests: write
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@<full-commit-sha> # v4
- env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: echo "Triaging: $PR_TITLE"
- uses: some-org/label-action@<full-commit-sha> # v2.1.0The original runs a fork's code with full secrets and a write-all token, pastes the PR title into a shell script, and trusts whatever is on the action's main branch. The fix uses the pull_request trigger, scopes the token, passes the title through an environment variable so the shell treats it as data, and pins actions by commit SHA.
Illustrative code, simplified for clarity — not taken from a customer repository.
What OpenRouting checks in your repository
- GitHub Actions and GitLab CI files: triggers, permissions blocks, checkout refs
- Event fields expanded inside run: scripts
- Third-party actions and images referenced by tag or branch instead of SHA or digest
- Secrets echoed, written to artifacts or passed to untrusted steps
- Build scripts that download and execute remote code
Scope and limits
- It reviews pipeline definitions in the repository; it doesn't read your CI provider's run logs, organization settings or stored secrets.
- Branch protection, required reviewers and environment approvals live in repository settings and aren't checked.
Coverage areas reflect OpenRouting's check library. Code, secret and infrastructure scanning run today; other areas are rolling out. Scanners surface candidates and a review agent decides whether each one is real — it doesn't promise to find every issue.
Review agents for this area
- CI/CD pipeline — Checks pipelines for leaked secrets, untrusted code execution and over-broad tokens.
- Supply chain — Checks dependency and build-time trust: pinning, lockfiles, registries and remote code.
- Secrets & data exposure — Judges whether a flagged value is really a secret and whether sensitive data leaks through logs or errors.
Common questions
Is pull_request_target always a finding?
No. It is safe when the workflow doesn't check out or run the PR's code. The CI/CD agent checks the steps and marks safe uses as likely false positives with the reason.
Does it support GitLab CI?
Yes, .gitlab-ci.yml is reviewed for the same classes: untrusted variables in scripts, protected-variable exposure and unpinned images.