| name | cicd |
| description | CI/CD pipeline attack category — poisoned pipeline execution, GitHub Actions expression injection, self-hosted runner abuse, secrets/OIDC exfil. Routing skill: fingerprint the CI provider + workflow surface, then load the matching leaf. |
| allowed-tools | Bash Read Write |
| metadata | {"subdomain":"reconnaissance","when_to_use":"ci cd pipeline github actions gitlab ci jenkins circleci buildkite drone azure devops travis workflow runner secrets oidc ppe pipeline injection","tags":"ci-cd, supply-chain, pipeline, github-actions, runner","mitre_attack":"T1195, T1199, T1078, T1554"} |
CI/CD Pipeline Exploitation — Category Overview
Routing skill for attacks against build / deployment pipelines. Pipelines run attacker-influenced code (PRs, dependencies, build scripts) with privileged tokens, cloud OIDC, and write access to artifacts that downstream consumers trust. Compromise of a single pipeline often equals compromise of every release built by it.
Sub-Skills
| Sub-Skill | Covers | When to Load |
|---|
| poisoned-pipeline-execution | Direct + Indirect PPE: injecting commands via attacker-controllable build files (Makefile, package.json scripts, build.gradle, Dangerfile, .pre-commit-config.yaml), pull_request_target abuse, fork-PR build triggers, dependency/test-script execution. | Target builds untrusted PR code; you can land a malicious file or dependency. |
| github-actions-injection | ${{ }} template injection via untrusted context (issue/PR title, body, branch name, commit message) into run: steps, pull_request_target + PR-head checkout, GITHUB_TOKEN permission abuse, artifact/cache poisoning, action pinning (tag vs SHA). | Target uses GitHub Actions and accepts external contributors. |
| self-hosted-runner-abuse | Non-ephemeral runner persistence, fork-PR job execution on self-hosted, runner-label targeting, secret theft from runner env, lateral movement into internal network / cloud metadata. | Target advertises self-hosted runners (workflow runs-on: label or public job logs). |
| cicd-secrets-exfil | Extracting CI secrets / OIDC tokens: echo / printenv exfil, masking bypass (base64, char-split), OIDC -> cloud role assumption, GITHUB_TOKEN / CI_JOB_TOKEN scope abuse, cache / artifact secret leakage. | You already have code execution in a CI job; need to convert it into durable cloud / registry access. |
Provider fingerprinting
ls -la <REPO>/.github/workflows/ 2>/dev/null
gh api "repos/<OWNER>/<REPO>/actions/workflows" --jq '.workflows[] | {name,path,state}'
test -f <REPO>/.gitlab-ci.yml && echo "GitLab CI"
ls <REPO>/.gitlab/ci/ 2>/dev/null
test -f <REPO>/Jenkinsfile && echo "Jenkins"; find <REPO> -name 'Jenkinsfile*' -type f
for f in .circleci/config.yml .buildkite/pipeline.yml .drone.yml azure-pipelines.yml .travis.yml; do
test -f "<REPO>/$f" && echo "$f"
done
grep -RhoE 'github\.com/[^/]+/[^/]+/actions|gitlab\.com/[^/]+/[^/]+/-/pipelines|circleci\.com/gh/|app\.travis-ci\.com' <REPO> 2>/dev/null | sort -u
Workflow file recon (GitHub Actions example)
find <REPO>/.github/workflows -type f \( -name '*.yml' -o -name '*.yaml' \) -print
gh api "repos/<OWNER>/<REPO>/contents/.github/workflows" --jq '.[].name'
for wf in $(gh api "repos/<OWNER>/<REPO>/contents/.github/workflows" --jq '.[].path'); do
echo "=== $wf ==="
gh api "repos/<OWNER>/<REPO>/contents/$wf" --jq '.content' | base64 -d
done
Risky-surface triage
| Signal | Why it matters | Grep |
|---|
pull_request_target: trigger | Runs with write GITHUB_TOKEN + secrets while checking out attacker code | grep -rE '^\s*pull_request_target\s*:' .github/workflows/ |
actions/checkout with ref: ${{ github.event.pull_request.head.sha }} under pull_request_target | Pulls attacker code with privileged context | grep -rE 'pull_request\.head' .github/workflows/ |
${{ github.event.* }} interpolated into a run: block | Expression injection sink (issue/PR body, title, branch name, commit msg) | grep -rE '\$\{\{\s*github\.event\.(issue|pull_request|comment|head_commit)' .github/workflows/ |
runs-on: [self-hosted, ...] on public repo | Self-hosted runner reachable from fork PRs | grep -rE 'runs-on:\s*(\[\s*self-hosted|self-hosted)' .github/workflows/ |
Third-party action pinned by tag (@v3) instead of SHA | Action repo / tag retargeting → silent supply-chain | grep -rE 'uses:\s*[^/]+/[^@]+@v?[0-9]' .github/workflows/ |
permissions: block missing or write-all | Token over-scoped; abuse to push to protected branches, publish releases | `grep -rE 'permissions: |
Secret-exposure surface
grep -rnE 'secrets\.|vars\.|env\.[A-Z_]+_TOKEN|env\.[A-Z_]+_KEY|id-token:\s*write|configure-aws-credentials|google-github-actions/auth' .github/workflows/
gh run list --repo <OWNER>/<REPO> --limit 20 --json databaseId,name,status,conclusion
gh run view <RUN_ID> --repo <OWNER>/<REPO> --log | grep -iE 'token|secret|password|aws_|gcp_|azure_' | head
Tooling
| Tool | Use |
|---|
gh (GitHub CLI) | Recon, workflow listing, run/log inspection, PR creation |
gato / gato-x (praetorian-inc) | GitHub Actions attack toolkit — self-hosted runner enum, PPE, secret exfil chains |
actionlint | Local lint that flags many injection sinks — defenders use it; you can read its rules to find sinks |
octoscan / zizmor | Static scanners for GitHub Actions security issues |
tj-actions-changed-files CVE class (CVE-2025-30066) | Known compromised-action precedent; pattern to look for in any third-party action |
Burp Collaborator / interactsh | DNS / HTTP beacon for non-destructive PoC of code execution on a runner |
Decision gate
Before any active test, confirm in writing:
- The target program explicitly allows CI/CD testing (many programs scope this out — "infrastructure", "third-party CI" exclusions are common).
- PoC will use a beacon-only payload (DNS / HTTP callback). Do not exfiltrate real secrets to attacker-controlled storage; print the first 4 chars of a token to prove access, then stop.
- Any malicious branch / PR / fork is clearly labeled
security-research and is deletable on request.
- You will not push to protected branches, publish artifacts, or assume cloud roles. Prove the capability, do not exercise it.
Cross-references
- Supply-chain catalog:
/skills/standard/exploit/supplychain/SKILL.md
- OPSEC + scope discipline:
/skills/shared/opsec/SKILL.md
- Cloud OIDC follow-on: cloud / IAM enumeration skills after a successful OIDC token exchange