Blog · E.11 · Technical

CI/CD pipeline security testing

Your pipeline holds the keys to everything — source code, cloud credentials, the registry, production — and it runs code automatically on every push. That makes it one of the highest-value targets you own, and one of the least-tested: pipelines are usually built by developers, trusted implicitly, and never in a pentest scope. Here's the CI/CD attack surface, what to test across GitHub Actions, GitLab CI and Jenkins, and how to harden it.

CI/CDDevSecOpsSupply ChainGitHub ActionsSecrets
CI/CD risks: Poisoned Pipeline Execution · Secret Sprawl · Over-broad Permissions · Dependency & Supply-chain · Runner Compromise · Pipeline→Cloud/Prod Access CI/CD risks: Poisoned Pipeline Execution · Secret Sprawl · Over-broad Permissions · Dependency & Supply-chain · Runner Compromise · Pipeline→Cloud/Prod Access
// TL;DR

The CI/CD pipeline is a highly privileged target — it holds credentials to code, cloud, registries and production and auto-builds the software users run, so compromising it enables a supply-chain attack. The key risks: poisoned pipeline execution (untrusted input running code with pipeline privileges), secret sprawl, over-broad permissions, dependency/supply-chain integrity (unpinned third-party actions), runner compromise, and the pipeline→cloud/production connection. Testing combines configuration review with real attack scenarios (exfiltrate a secret, tamper with a build) across GitHub Actions, GitLab CI and Jenkins. Critically, a standard pentest usually doesn't include the pipeline — scope it in explicitly. Full breakdown below; the cloud it deploys to is covered in cloud penetration testing.

// 01 Why the pipeline is a top target

Think about what your CI/CD system can do. It can read all your source code. It holds credentials to your cloud accounts, container registry and package repositories. It builds artifacts and pushes them to production automatically. In privilege terms, the pipeline often rivals your most powerful admin — yet it's usually configured by developers optimising for velocity, trusted implicitly, and left out of security reviews. That gap is why attackers love it: compromise the pipeline and you don't need to breach production directly, you just inject malicious code into a legitimate build and let the pipeline deploy it for you. That's the essence of a modern software supply-chain attack — and it's why the pipeline deserves testing as rigorous as the app it ships.

// 02 The attack surface

01

Poisoned execution

Untrusted input (a PR, a modified build script) running attacker code with the pipeline's privileges.

02

Secrets

Credentials and tokens over-scoped, exposed to jobs, or leaked into logs and artifacts.

03

Supply chain

Unpinned third-party actions/dependencies and unverified provenance pulled into builds.

04

Runners & access

Self-hosted runner compromise, and the pipeline's standing access into cloud and production.

// 03 Poisoned pipeline execution (PPE)

The signature CI/CD attack is Poisoned Pipeline Execution: an adversary who can influence what the pipeline runs gets it to execute malicious commands with the pipeline's privileges. The classic form is a pull request that modifies a build script — if that PR triggers a workflow with access to secrets, the attacker's code runs inside your trusted CI environment. Open-source projects and any repo accepting external contributions are especially exposed, because a fork's PR can trigger a privileged workflow. From there, PPE leads straight to secret theft, tampered artifacts and malicious deployment. The defensive question a test answers is precise: what can untrusted input actually trigger, and with what access? Getting the boundary between untrusted contributions and privileged workflows right is the single most important CI/CD control.

// 04 Secrets & supply-chain integrity

Two more failure modes dominate real findings. Secret sprawl: pipelines accumulate long-lived, over-scoped credentials — a cloud key with far more permission than the job needs, a token readable by every workflow, a secret echoed into a build log. Testing checks how secrets are stored, scoped per-job, and whether they leak into logs or artifacts; the fix is least-privilege, short-lived, ideally OIDC-federated credentials. Supply-chain integrity: pipelines pull in third-party actions, base images and dependencies, often unpinned — a tag like @v3 that silently updates, or an action from an unverified author. If any of those is compromised, so is your build. Testing looks for pinned versions (by digest), verified provenance, and controls on which external components a pipeline may use. This is the same discipline modern frameworks like DORA and supply-chain guidance push toward.

// 05 Testing across platforms — and the scope trap

The concepts are universal but the mechanics differ by platform: GitHub Actions (workflow permissions, pull_request_target, OIDC), GitLab CI (protected branches/variables, runner tags), Jenkins (plugin sprawl, script security, agent isolation). A competent test blends configuration review with practical attack scenarios — attempt to exfiltrate a secret via a crafted PR, try to tamper with a build artifact, see whether a compromised runner can reach production. But here's the trap most teams miss: a standard application or network pentest usually does not include the pipeline. It focuses on the running app and infra, and the CI/CD system falls outside scope — leaving your most privileged asset untested. Scope it in explicitly, as part of a broader engagement or a focused DevSecOps assessment, and pair it with testing of the cloud it deploys into, per our methodology.

// 06 Frequently asked questions

Why is the CI/CD pipeline a high-value target?

It's highly privileged — it holds credentials to code, cloud, registries and production and auto-builds and deploys your software. Compromising it lets an attacker steal secrets, inject malicious code into legitimate builds, and reach production indirectly (a supply-chain attack). Pipelines are often trusted implicitly and configured by developers, so they carry over-broad permissions and exposed secrets.

What is poisoned pipeline execution?

PPE is when an adversary who can influence the pipeline's config or the code it runs makes it execute malicious commands with its privileges — e.g. a PR modifying a build script, or an untrusted PR triggering a workflow with secret access. Because the pipeline holds powerful credentials, PPE leads to secret theft, tampered artifacts and malicious deployment.

What should CI/CD security testing cover?

Pipeline configuration and permissions (least privilege, protected branches, who can change workflows), secrets management, poisoned-pipeline-execution risk from untrusted input, dependency and supply-chain integrity (pinned versions, provenance, third-party actions), build runner security, and the pipeline's connections into cloud and production. It combines configuration review with practical attack scenarios.

Does a normal pentest cover the pipeline?

Often not. A standard application or network test focuses on the running app and infrastructure, and the pipeline can fall outside scope. Because it's a distinct, highly privileged surface with its own risks — poisoned execution, secret sprawl, supply-chain integrity — scope it in explicitly, as part of a broader engagement or a focused DevSecOps assessment.

// 07 Related reading

UG

Usama Gul

Founder & Penetration Testing Lead, CyberFortify

Tests CI/CD pipelines across GitHub Actions, GitLab CI and Jenkins — poisoned execution, secret sprawl and supply-chain integrity — the privileged blind spot most standard pentests never touch.

Is your pipeline in scope?

Most pentests skip the CI/CD system — your most privileged asset. We'll test it explicitly: poisoned execution, secrets, supply-chain integrity and the path from a pull request to production.

Scope a DevSecOps test → Cloud testing →