All skills
getsentry avatar

/gha-security-review

@e99aa67 official
by Sentrygetsentry/skills1k stars
53

GitHub Actions security review for workflow exploitation vulnerabilities. Use when asked to "review GitHub Actions", "audit workflows", "check CI security", "GHA security", "workflow security review", or review .github/workflows/ for pwn requests, expression injection, credential theft, and supply chain attacks. Exploitation-focused with concrete PoC scenarios.

Use this Skill: https://skilld.dev/gh/getsentry/skills/gha-security-review

This session only. Nothing lands on disk.

referencessupply-chain.md

≈2.4k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Supply Chain: Third-Party Actions

Overview

GitHub Actions workflows depend on third-party actions referenced by uses:. If these actions are not pinned to immutable references (full commit SHAs), attackers can compromise them via tag mutation, account takeover, or fork-and-replace attacks.

Policy: pin third-party actions and reusable workflows to a full 40-character commit SHA. Do not require SHA pins for first-party GitHub actions (actions/*, github/*) on version tags, or for same-repo / vendored actions.


What Counts As Third-Party

Source Classification Pinning finding?
actions/* (GitHub official) First-party No — version tags are fine
github/* (GitHub org) First-party No — version tags are fine
Same-repo / vendored (./.github/actions/...) Not third-party supply chain No as supply-chain pinning (still review in pwn-request context)
Org-owned / internal first-party actions when reviewing that org's repos First-party for that org No unless the action is external to the org's trust boundary
External orgs (aws-actions, docker, tj-actions, community, unknown) Third-party Yes — pin to full SHA when privilege makes it relevant

When org ownership is unclear, treat non-actions/* / non-github/* / non-local refs as third-party.


Pinning: Tags vs. SHAs

Reportable: Unpinned Third-Party Tags

# REPORT when third-party and the job is privileged enough (see severity)
- uses: some-org/some-action@v1     # Tag — mutable third-party
- uses: tj-actions/changed-files@v44
- uses: docker/build-push-action@v6
- uses: some-org/some-action@main   # Branch — mutable

Tags are mutable Git references. The maintainer (or attacker with write access) can delete and recreate a tag pointing to a different commit. When the tag is updated, every workflow using that tag runs the new code.

Safe: Third-Party SHA Pinning

# SAFE for third-party: commit SHA is immutable
- uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83  # v6.18.0
- uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502  # v4.0.2

SHAs are immutable — once a commit exists, its SHA cannot change. Pin third-party actions to the full 40-character SHA and add a comment with the version for readability.

Do Not Report: First-Party Version Tags

# NOT a supply-chain pinning finding
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/upload-artifact@v4
- uses: github/codeql-action/analyze@v3
- uses: ./.github/actions/local-build

First-party actions/* and github/* on version tags are not findings by themselves. Same-repo or vendored actions are not third-party supply-chain findings (they can still be unsafe if loaded from a PR-controlled checkout — that is a pwn-request / trust-crossing issue, not pinning).


Attack Vectors

Tag Mutation Attack

  1. Attacker compromises a popular third-party action's repository (phishing, leaked credentials, insider)
  2. Deletes the v1 tag
  3. Creates a new v1 tag pointing to a malicious commit
  4. Every workflow using @v1 now runs the attacker's code

This is not theoretical — CVE-2025-30066 (tj-actions/changed-files) and related incidents showed tag rewrites can leak secrets at scale.

Account Takeover / Org Compromise

If a third-party action author's GitHub account is compromised:

  • All actions under that account can be backdoored
  • Version tags can be silently updated
  • Users won't notice unless they're pinned to SHAs

Fork-and-Replace

  1. Original action author deletes their repository
  2. Attacker creates a fork with the same owner/repo name
  3. Existing workflows that reference owner/repo@tag now pull from the attacker's fork

Actions That curl | bash at Runtime

Some actions download and execute external scripts at runtime:

# Action's action.yml — RISKY even when SHA-pinned
runs:
  using: composite
  steps:
    - run: curl -sSfL https://example.com/install.sh | bash
      shell: bash

Even if you pin the action to a SHA, the external URL can change. The action itself is immutable, but its runtime dependencies are not. Report this for third-party actions in privileged jobs; do not use it as a reason to demand SHA pins on first-party GitHub actions.


Detection Patterns

# Find third-party action references (exclude first-party + local)
grep -rn "uses:" .github/workflows/ \
  | grep -v "#" \
  | grep -v "uses: \\.\\/" \
  | grep -v "actions/" \
  | grep -v "github/"

# Among third-party refs, find unpinned tags/branches (not full SHA)
grep -rn "uses:" .github/workflows/ \
  | grep -v "#" \
  | grep -v "uses: \\.\\/" \
  | grep -v "actions/" \
  | grep -v "github/" \
  | grep -v "@[0-9a-f]\\{40\\}"

# Find third-party actions pinned to branch names
grep -rn "uses:" .github/workflows/ \
  | grep -v "actions/\\|github/\\|\\./" \
  | grep -E "@(main|master|develop|latest)"

Do not treat every non-SHA uses: as a finding. Filter to third-party first, then assess job privilege.


When To Report

Report mutable third-party actions only when job privilege makes compromise security-relevant.

Shape Severity
Mutable third-party ref in package publishing, release signing, protected-branch push, production deploy, or token-minting job High / Critical (unknown org + pull_request_target / secrets → Critical)
Mutable third-party ref with secrets, OIDC, or non-trivial write-scoped GITHUB_TOKEN High or Medium depending on blast radius
Pinned third-party action that downloads and executes mutable remote scripts in a privileged job Medium, or High when the downloaded payload runs inside the privileged step
Mutable third-party ref in public read-only CI with no secrets and no write scopes No finding unless adjacent to another traced workflow risk
Unpinned first-party actions/* / github/* version tags No finding
Local / vendored action pinning No finding as supply chain (review pwn-request separately)

Risk Assessment by Third-Party Source

Use this only after the ref is classified third-party and the job is privileged enough to report:

Source Risk Action
Major orgs (aws-actions, google-github-actions, docker) Medium Pin to SHA
Popular community actions (1k+ stars) Medium Pin to SHA, review source
Less-known actions (under 100 stars) High Pin to SHA, review source carefully, consider vendoring
Unknown / single-maintainer Critical Vendor locally or replace with inline run:

The Fix: SHA Pin Third-Party Actions

steps:
  # First-party: version tags are fine — do not flag
  - uses: actions/checkout@v4
  - uses: actions/setup-node@v4

  # Third-party: pin to SHA, comment with version for readability
  - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83  # v6.18.0
  - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502  # v4.0.2

Automated Pinning

Tools that can pin and update third-party action SHAs:

  • Dependabot — GitHub native, updates action SHAs
  • Renovate — Can pin and update actions
  • StepSecurity Secure Workflows — Can pin actions to SHAs (configure to match third-party-only policy if you do not want first-party pins)

Vendoring Critical Actions

For high-security workflows, vendor the third-party action locally:

# Instead of: uses: some-org/critical-action@v1
# Copy the action into your repo:
- uses: ./.github/actions/critical-action

Severity Guidelines

Pattern Severity Rationale
Unpinned third-party action from unknown org used in pull_request_target Critical Attacker could backdoor the action AND access secrets
Unpinned third-party action from known org in sensitive/privileged workflow High Tag mutation risk with secret exposure
Unpinned third-party action with limited privilege but real write/secret surface Medium Real supply-chain risk, bounded blast radius
Third-party action that curls external scripts at runtime in a privileged job High Even SHA-pinned actions can be compromised via external deps
Unpinned first-party actions/* / github/* Do not report Outside pinning policy
Local action (./.github/actions/) unpinned Do not report as pinning Controlled by repo; only risky in pwn-request context

Exploitation Scenario Template

ATTACK: Supply Chain via [unpinned third-party action / tag mutation / curl|bash]
ENTRY: Attacker compromises [third-party action repo / account / external URL]
PAYLOAD: Malicious code in [action.yml / downloaded script]
TRIGGER: Workflow [file:line] uses third-party [action@tag] without SHA pin
EXECUTION: Modified action runs with workflow permissions
IMPACT: [RCE with workflow permissions, secret theft, etc.]

References

Source: SKILL.md on GitHub

2 alerts1d5 checks · Risk CRITICAL
  • Gen Agent Trust Hub1d

    This skill is a defensive security toolkit designed to audit GitHub Actions workflows for common vulnerabilities. It provides educational references and concrete examples of exploitation techniques such as shell injection, pwn requests, and credential escalation. While the skill contains code snippets and URLs associated with real-world attacks—documented as pedagogical examples to assist auditors—its intent is purely defensive and educational.

  • Socket1d

    2 alerts: gptSecurity

  • Snyk1d

    Risk: LOW · No issues

  • Runlayer7mo

    9/10 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at e99aa67. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated last week
All 1 allowed tools
Read Grep Glob Bash Task
  • github-actions
  • workflow-security
  • ci-cd
  • expression-injection
  • supply-chain
  • pull-request-target
  • credential-theft
  • yaml

README badge

README badge for getsentry/skills/gha-security-review

Audits GitHub Actions workflows for externally-exploitable vulnerabilities including expression injection, credential theft, and pwn-request patterns. The skill traces complete attack paths from fork PRs and comments through to execution, and reports only HIGH and MEDIUM confidence findings with concrete proof-of-concept scenarios.

Generated from the current SKILL.md.

What threat model does this skill use?
The skill focuses on vulnerabilities exploitable by external attackers without write access — those who can open PRs from forks, create issues, and post comments. It does not flag vulnerabilities that require repository write access, such as workflow_dispatch input injection or expression injection in push-only workflows on protected branches.
What confidence levels does this skill report?
Only HIGH and MEDIUM confidence findings. HIGH requires a complete traced attack path with exploitation scenario. MEDIUM indicates a partially confirmed attack path that needs verification. LOW confidence theoretical issues are not reported.
What types of GitHub Actions vulnerabilities does this skill check for?
The skill checks for pwn request exploitation, expression injection, unauthorized command execution via issue comments, credential escalation, config file poisoning, insecure third-party action pinning, and unsafe permissions or secrets scoping.
Does this skill flag all uses of pull_request_target?
No. pull_request_target is only flagged if the workflow also checks out fork code or executes code from the PR. pull_request_target without fork checkout is marked as safe.
Does this skill review workflows in other repositories?
No. The skill reviews workflows in the provided repository only. Dependencies on workflows in other repositories are noted but not audited.

Generated from the current SKILL.md. These answers refresh after source changes.