CtrlK
BlogDocsLog inGet started
Tessl Logo

cicd

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.

73

Quality

91%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

SKILL.md
Quality
Evals
Security

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-SkillCoversWhen to Load
poisoned-pipeline-executionDirect + 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-abuseNon-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-exfilExtracting 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

# GitHub Actions
ls -la <REPO>/.github/workflows/ 2>/dev/null
gh api "repos/<OWNER>/<REPO>/actions/workflows" --jq '.workflows[] | {name,path,state}'

# GitLab CI
test -f <REPO>/.gitlab-ci.yml && echo "GitLab CI"
ls <REPO>/.gitlab/ci/ 2>/dev/null

# Jenkins
test -f <REPO>/Jenkinsfile && echo "Jenkins"; find <REPO> -name 'Jenkinsfile*' -type f

# CircleCI / Buildkite / Drone / Azure / Travis
for f in .circleci/config.yml .buildkite/pipeline.yml .drone.yml azure-pipelines.yml .travis.yml; do
  test -f "<REPO>/$f" && echo "$f"
done

# Provider hints in README / badges
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)

# Local checkout
find <REPO>/.github/workflows -type f \( -name '*.yml' -o -name '*.yaml' \) -print

# Remote, no clone needed
gh api "repos/<OWNER>/<REPO>/contents/.github/workflows" --jq '.[].name'

# Pull every workflow at HEAD
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

SignalWhy it mattersGrep
pull_request_target: triggerRuns with write GITHUB_TOKEN + secrets while checking out attacker codegrep -rE '^\s*pull_request_target\s*:' .github/workflows/
actions/checkout with ref: ${{ github.event.pull_request.head.sha }} under pull_request_targetPulls attacker code with privileged contextgrep -rE 'pull_request\.head' .github/workflows/
${{ github.event.* }} interpolated into a run: blockExpression 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 repoSelf-hosted runner reachable from fork PRsgrep -rE 'runs-on:\s*(\[\s*self-hosted|self-hosted)' .github/workflows/
Third-party action pinned by tag (@v3) instead of SHAAction repo / tag retargeting → silent supply-chaingrep -rE 'uses:\s*[^/]+/[^@]+@v?[0-9]' .github/workflows/
permissions: block missing or write-allToken over-scoped; abuse to push to protected branches, publish releases`grep -rE 'permissions:

Secret-exposure surface

# Secrets and OIDC references — every line is a potential exfil target once you have RCE in a job
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/

# Exposed in public job logs (replays)
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

ToolUse
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
actionlintLocal lint that flags many injection sinks — defenders use it; you can read its rules to find sinks
octoscan / zizmorStatic 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 / interactshDNS / HTTP beacon for non-destructive PoC of code execution on a runner

Decision gate

Before any active test, confirm in writing:

  1. The target program explicitly allows CI/CD testing (many programs scope this out — "infrastructure", "third-party CI" exclusions are common).
  2. 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.
  3. Any malicious branch / PR / fork is clearly labeled security-research and is deletable on request.
  4. 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
Repository
PurpleAILAB/Decepticon
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.