gha-security-review
- Use it when:
- You want a repo's .github/workflows, its composite actions and the scripts they load checked for exploitable flaws.
- It does:
- Classifies each workflow's triggers, loads the matching attack references, runs eight checks from pwn requests and expression injection to supply chain and runners, and traces each attack.
- You get:
- Findings rated Critical to Medium, each with entry point, payload, how it runs, impact, a proof-of-concept sketch and a fix, plus Needs verification and Reviewed and cleared lists.
- Threat model:
- Only attackers without write access, who can open fork PRs, issues and comments; workflow_dispatch inputs and protected-branch pushes are out of scope.
- Won't flag:
- Safe patterns such as expressions in if: or with:, SHA-pinned actions, or first-party actions on version tags.
- Unlike security-review:
- That one, Sentry's general security review, hands GitHub Actions workflows to this one when it's installed.
TL;DR
Sentry's review of CI workflows, built from attack patterns in real GitHub Actions exploits, including StepSecurity's analysis of the HackerBot Claw campaign. It looks for pull_request_target workflows that check out fork code, ${{ }} expressions expanded inside run: blocks, comment-triggered commands with no author check, long-lived tokens reachable by untrusted code, workflows that load CLAUDE.md, AGENTS.md or a Makefile from a PR, unpinned third-party actions in jobs with secrets or write access, over-broad permissions, and self-hosted runners, caches and artifacts. A finding needs a concrete exploitation scenario: with all five elements it is reported, with a broken link it goes under Needs verification, and theoretical issues are dropped. Before reporting, the agent reads each full workflow, traces the trigger and its if: conditions, confirms an outside attacker controls the value, and checks for mitigations. When nothing qualifies, it says no exploitable vulnerabilities were identified.
Summarizes the skill at e94f222.
npx skills add https://github.com/getsentry/skills --skill gha-security-review skills.sh pageSource on GitHubAll skills from getsentry/skills
- Total Downloads
- 5,000 on skills.sh, Nov 9, 2026
- Repo stars
- 1,135 getsentry/skills
- First seen
- Mar 3, 2026 on skills.sh
Weekly values
| Week to | Installs |
|---|---|
| Sep 21 | 52 |
| Sep 28 | 38 |
| Oct 5 | 383 |
| Oct 12 | 72 |
| Oct 19 | 77 |
| Oct 26 | 79 |
| Nov 2 | 111 |
| Nov 9 | 83 |
| Category |
Compliance, guardrails, skill vetting and browser fingerprinting. Find root causes, review code and test what you built. Everything for building software: planning, coding, debugging, design, frameworks, cloud, agents and skills. |
|---|---|
| Type |
A multi-step process the agent follows: interview, debug, run a TDD loop, review. |
| Effect |
Adds no side effects of its own. It shapes how the agent thinks, writes or reviews. Guidelines and routers are always effect:none, even when the task they support edits code. |
| Needs |
Instructions only. Works in any agent that supports skills. |
| Publisher |
A verified publisher on skills.sh, or the company or maintainer behind the product the skill operates. |
| Topics | |
| Stack |
SKILL.md
From getsentry/skills at e94f222. Checked daily, last changed Nov 7, 2026.
Frontmatter
name: gha-security-review
description: '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.'
allowed-tools: Read Grep Glob Bash Task<!-- Attack patterns and real-world examples sourced from the HackerBot Claw campaign analysis by StepSecurity (2025): https://www.stepsecurity.io/blog/hackerbot-claw-github-actions-exploitation -->
GitHub Actions Security Review
Find exploitable vulnerabilities in GitHub Actions workflows. Every finding MUST include a concrete exploitation scenario — if you can't build the attack, don't report it.
This skill encodes attack patterns from real GitHub Actions exploits — not generic CI/CD theory.
Scope
Review the workflows provided (file, diff, or repo). Research the codebase as needed to trace complete attack paths before reporting.
Files to Review
.github/workflows/*.yml— all workflow definitionsaction.yml/action.yaml— composite actions in the repo.github/actions/*/action.yml— local reusable actions- Config files loaded by workflows:
CLAUDE.md,AGENTS.md,Makefile, shell scripts under.github/
Out of Scope
- Workflows in other repositories (only note the dependency)
- GitHub App installation permissions (note if relevant)
Threat Model
Only report vulnerabilities exploitable by an external attacker — someone without write access to the repository. The attacker can open PRs from forks, create issues, and post comments. They cannot push to branches, trigger workflow_dispatch, or trigger manual workflows.
Do not flag vulnerabilities that require write access to exploit:
workflow_dispatchinput injection — requires write access to trigger- Expression injection in
push-only workflows on protected branches workflow_callinput injection where all callers are internal- Secrets in
workflow_dispatch/schedule-only workflows
Confidence
Report only HIGH and MEDIUM confidence findings. Do not report theoretical issues.
| Confidence | Criteria | Action |
|---|---|---|
| HIGH | Traced the full attack path, confirmed exploitable | Report with exploitation scenario and fix |
| MEDIUM | Attack path partially confirmed, uncertain link | Report as needs verification |
| LOW | Theoretical or mitigated elsewhere | Do not report |
For each HIGH finding, provide all five elements:
- Entry point — How does the attacker get in? (fork PR, issue comment, branch name, etc.)
- Payload — What does the attacker send? (actual code/YAML/input)
- Execution mechanism — How does the payload run? (expression expansion, checkout + script, etc.)
- Impact — What does the attacker gain? (token theft, code execution, repo write access)
- PoC sketch — Concrete steps an attacker would follow
If you cannot construct all five, report as MEDIUM (needs verification).
Step 1: Classify Triggers and Load References
For each workflow, identify triggers and load the appropriate reference:
| Trigger / Pattern | Load Reference |
|---|---|
pull_request_target |
references/pwn-request.md |
issue_comment with command parsing |
references/comment-triggered-commands.md |
${{ }} in run: blocks |
references/expression-injection.md |
| PATs / deploy keys / elevated credentials | references/credential-escalation.md |
| Checkout PR code + config file loading | references/ai-prompt-injection-via-ci.md |
| Third-party actions (especially unpinned) | references/supply-chain.md |
permissions: block or secrets usage |
references/permissions-and-secrets.md |
| Self-hosted runners, cache/artifact usage | references/runner-infrastructure.md |
| Any confirmed finding | references/real-world-attacks.md |
Load references selectively — only what's relevant to the triggers found.
Step 2: Check for Vulnerability Classes
Check 1: Pwn Request
Does the workflow use pull_request_target AND check out fork code?
- Look for
actions/checkoutwithref:pointing to PR head - Look for local actions (
./.github/actions/) that would come from the fork - Check if any
run:step executes code from the checked-out PR
Check 2: Expression Injection
Are ${{ }} expressions used inside run: blocks in externally-triggerable workflows?
- Map every
${{ }}expression in everyrun:step - Confirm the value is attacker-controlled (PR title, branch name, comment body — not numeric IDs, SHAs, or repository names)
- Confirm the expression is in a
run:block, notif:,with:, or job-levelenv:
Check 3: Unauthorized Command Execution
Does an issue_comment-triggered workflow execute commands without authorization?
- Is there an
author_associationcheck? - Can any GitHub user trigger the command?
- Does the command handler also use injectable expressions?
Check 4: Credential Escalation
Are elevated credentials (PATs, deploy keys) accessible to untrusted code?
- What's the blast radius of each secret?
- Could a compromised workflow steal long-lived tokens?
Check 5: Config File Poisoning
Does the workflow load configuration from PR-supplied files?
- AI agent instructions:
CLAUDE.md,AGENTS.md,.cursorrules - Build configuration:
Makefile, shell scripts
Check 6: Supply Chain
Are third-party actions securely pinned to full SHAs?
- Pin third-party / external actions and reusable workflows only
- Do not flag first-party
actions/*orgithub/*on version tags - Do not flag same-repo / vendored (
./.github/actions/...) as supply-chain pinning issues - Only report when the job has secrets, OIDC, write token, release, deploy, package, or signing power — unprivileged read-only CI is not a finding
Check 7: Permissions and Secrets
Are workflow permissions minimal? Are secrets properly scoped?
Check 8: Runner Infrastructure
Are self-hosted runners, caches, or artifacts used securely?
Safe Patterns (Do Not Flag)
Before reporting, check if the pattern is actually safe:
| Pattern | Why Safe |
|---|---|
pull_request_target WITHOUT checkout of fork code |
Never executes attacker code |
${{ github.event.pull_request.number }} in run: |
Numeric only — not injectable |
${{ github.repository }} / github.repository_owner |
Repo owner controls this |
${{ secrets.* }} |
Not an expression injection vector |
${{ }} in if: conditions |
Evaluated by Actions runtime, not shell |
${{ }} in with: inputs |
Passed as string parameters, not shell-evaluated |
| Third-party actions pinned to full SHA | Immutable reference |
First-party actions/* / github/* on version tags |
Outside third-party pinning policy — do not flag |
| Same-repo / vendored local actions | Not third-party supply chain (review pwn-request separately) |
pull_request trigger (not _target) |
Runs in fork context with read-only token |
Any expression in workflow_dispatch/schedule/push to protected branches |
Requires write access — outside threat model |
Key distinction: ${{ }} is dangerous in run: blocks (shell expansion) but safe in if:, with:, and env: at the job/step level (Actions runtime evaluation).
Step 3: Validate Before Reporting
Before including any finding, read the actual workflow YAML and trace the complete attack path:
- Read the full workflow — don't rely on grep output alone
- Trace the trigger — confirm the event and check
if:conditions that gate execution - Trace the expression/checkout — confirm it's in a
run:block or actually references fork code - Confirm attacker control — verify the value maps to something an external attacker sets
- Check existing mitigations — env var wrapping, author_association checks, restricted permissions, SHA pinning
If any link is broken, mark MEDIUM (needs verification) or drop the finding.
If no checks produced a finding, report zero findings. Do not invent issues.
Step 4: Report Findings
## GitHub Actions Security Review
### Findings
#### [GHA-001] [Title] (Severity: Critical/High/Medium)
- **Workflow**: `.github/workflows/release.yml:15`
- **Trigger**: `pull_request_target`
- **Confidence**: HIGH — confirmed through attack path tracing
- **Exploitation Scenario**:
1. [Step-by-step attack]
- **Impact**: [What attacker gains]
- **Fix**: [Code that fixes the issue]
### Needs Verification
[MEDIUM confidence items with explanation of what to verify]
### Reviewed and Cleared
[Workflows reviewed and confirmed safe]
If no findings: "No exploitable vulnerabilities identified. All workflows reviewed and cleared."