Skip to content
github actions securityci cd securitysupply chain attacks

GitHub Actions Security Guide for Penetration Testers

GitHub Actions Security Guide for Penetration Testers

A real GitHub Actions compromise rarely starts with a flashy zero-day. It starts with a pull request, a reused third-party action, an over-scoped token, or a secret exposed to the wrong trigger. Once an attacker gets code execution inside a runner, the question is no longer whether the workflow is vulnerable. The question is what that runner can reach before anyone notices.

Treat GitHub Actions like an attack path, not a build feature. The workflow file is only the entry point. A pentest usually maps four layers: trigger abuse, runner execution, token and secret access, then pivot paths into the repo, package registries, and cloud control plane. Teams that skip that sequence waste time fixing low-impact lint jobs while a deploy workflow still holds write access to production. Start by mapping the workflow attack surface with attack surface mapping before prioritizing exploit paths.

The first pivot is usually identity. GITHUB_TOKEN permissions, inherited repository secrets, OpenID Connect trust policies, and long-lived cloud credentials define the blast radius far more than the YAML syntax does. If a workflow triggered from untrusted input can write to the repository, an attacker can push code, tamper with release artifacts, or modify the pipeline to survive cleanup. If that same job can assume a cloud role, the compromise jumps from CI to infrastructure fast.

Self-hosted runners change the math again. They often sit closer to internal systems, keep more tooling installed, and get patched less often than teams admit. On an engagement, I care less about the initial runner foothold than about what persists after the job ends: cached credentials, Docker socket access, mounted volumes, artifact poisoning, and network paths into build systems that were never meant to face hostile code.

This is why exploitability has to come before checklist compliance.

A public repository with strict token scopes and isolated ephemeral runners may be noisy but contained. A private monorepo with generous secrets, reusable workflows, and deployment federation can be quieter and far more dangerous. The attack chain matters because each step compounds access. Compromise the workflow, reach the source. Reach the source, alter the build. Alter the build, inherit the cloud.