Pentesting CI/CD Methodology
VCS
VCS stands for Version Control System; these systems allow developers to manage their source code. The most common one is Git, a distributed version-control system, and you will usually find companies using it in one of the following platforms. [5]
- Github
- Gitlab
- Bitbucket
- Gitea
- Gitblit
- Cloud providers (they offer their own VCS platforms). [5]
CI/CD Pipelines
CI/CD pipelines enable developers to automate the execution of code for various purposes, including building, testing, and deploying applications. These automated workflows are triggered by specific actions, such as code pushes, pull requests, or scheduled tasks. They are useful for streamlining the process from development to production. [1][9][10][11][12]
However, these systems need to be executed somewhere and usually with privileged credentials to deploy code or access sensitive information. [1][13][14]
VCS Pentesting Methodology
[!NOTE] Even if some VCS platforms allow to create pipelines for this section we are going to analyze only potential attacks to the control of the source code.
Platforms that contain the source code of your project contain sensitive information, so people need to be very careful with the permissions granted inside these platforms. These are some common problems across VCS platforms that an attacker could abuse. [5]
- Leaks: If your code contains leaks in commits and the attacker can access the repository (because it is public or because they have access), they could discover the leaks. [5]
- Access: If an attacker can access an account inside the VCS platform, they could gain more visibility and permissions. [6][27]
- Register: Some platforms will allow external users to create an account. [6]
- SSO: Some platforms will not allow users to register, but will allow anyone to access with a valid SSO identity. [6]
- Credentials: Username/passwords, personal tokens, SSH keys, OAuth tokens, and cookies are among the credentials an attacker could steal to access a repository. [6][15][27]
- Webhooks: VCS platforms allow users to generate webhooks. If they are not protected with high-entropy secrets and signature validation, an attacker could abuse them. [7]
- Code compromise: If a malicious actor has some kind of write access over the repositories, they could try to inject malicious code. To be successful, they might need to bypass branch protections. [8]
Pipelines Pentesting Methodology
The most common way to define a pipeline is by using a CI configuration file hosted in the repository that the pipeline builds. This file describes the order of executed jobs, conditions that affect the flow, and build environment settings.
These files typically have a consistent name and format, for example — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), and the GitHub Actions YAML files located under .github/workflows. When triggered, the pipeline job pulls the code from the selected source (e.g. commit / branch), and runs the commands specified in the CI configuration file against that code. [1][9][10][11][12]
Therefore, the ultimate goal of the attacker is to somehow compromise those configuration files or the commands they execute. [1][4]
[!TIP] Some hosted builders let contributors choose the Docker build context and Dockerfile path. If the context is attacker-controlled, you may set it outside the repository (e.g., "..") to ingest host files during the build and exfiltrate secrets. [18][19] See:
{{#ref}} docker-build-context-abuse.md {{#endref}}
PPE - Poisoned Pipeline Execution
The Poisoned Pipeline Execution (PPE) path exploits permissions in an SCM repository to manipulate a CI pipeline and execute harmful commands. Users with the necessary permissions can modify CI configuration files or other files used by the pipeline job to include malicious commands. This "poisons" the CI pipeline, leading to the execution of these malicious commands. [1][4]
For a malicious actor to successfully perform a PPE attack, they need to be able to:
- Have write access to the VCS platform, as pipelines are usually triggered when a push or a pull request is performed. (See the VCS pentesting methodology for a summary of ways to get access.) [1][4][34]
- Even if they have write permissions, they need to be sure they can modify the CI config file or other files the config relies on. [1][4]
- For this, they might need to be able to bypass branch protections. [8]
There are three PPE flavours. [1][4]
- D-PPE: A Direct PPE attack occurs when the actor modifies the CI config file that is going to be executed. [1][4]
- I-PPE: An Indirect PPE attack occurs when the actor modifies a file the CI config file that is going to be executed relies on (like a makefile or a Terraform config). [1][4]
- Public PPE or 3PE: In some cases, pipelines can be triggered by users who do not have write access to the repository (and who might not even be part of the organization) because they can send a PR. [1][4][34]
Exploitation Benefits
Knowing the three flavours of pipeline poisoning, let us check what an attacker could obtain after a successful exploitation. [1][4]
- Secrets: As mentioned previously, pipelines require privileges for their jobs (retrieve the code, build it, deploy it, and so on), and these privileges are usually granted in secrets. These secrets are usually accessible via environment variables or files inside the system, so an attacker will try to exfiltrate as many secrets as possible. [1][13][14][35]
- Computation: The code is executed somewhere, and depending on where it is executed, an attacker might be able to pivot further. [1]
- On-Premises: If the pipelines are executed on premises, an attacker might end up in an internal network with access to more resources. [1]
- Cloud: The attacker could access other machines in the cloud and could exfiltrate IAM roles/service-account tokens from them to obtain further access inside the cloud. [1]
- Platform machines: Sometimes the jobs execute inside the pipeline platform's machines, which are usually inside a cloud with no additional access. [1]
- Select it: Sometimes the pipeline platform will have several configured machines, and if you can modify the CI configuration file, you can indicate where you want to run the malicious code. In this situation, an attacker might run a reverse shell on each possible machine to try to exploit it further. [1]
- Compromise production: If you are inside the pipeline and the final version is built and deployed from it, you could compromise the code that is going to end up running in production. [1]
Dependency & Registry Supply-Chain Abuse
Compromising a CI/CD pipeline or stealing credentials from it can let an attacker move from pipeline execution to ecosystem-wide code execution by backdooring dependencies or release tooling. [2]
- Install-time code execution via package hooks: publish a package version that adds
preinstall,postinstall,prepare, or similar hooks so the payload runs automatically on developer workstations and CI runners during dependency installation. [2][21] - Secondary execution paths: even if targets install with
--ignore-scripts, a malicious package can still register a common CLI name in thebinfield so the attacker-controlled wrapper is symlinked intoPATHand executes later when the command is used. [20][22] - Runtime bootstrapping: a small installer can download a second runtime or toolchain during installation (for example Bun or a packed interpreter) and then launch the main payload with it, avoiding local dependency requirements. [2][21]
- Credential harvesting from build environments: once code runs inside CI, check environment variables,
~/.npmrc,~/.git-credentials, SSH keys, cloud CLI configs, and local tooling such asgh auth token. On GitHub Actions, also look for runner-specific secrets and artifacts. [2][26][27][35][36] - Workflow injection with stolen GitHub tokens: a token with
repo+workflowpermissions can create a branch, commit a malicious file inside.github/workflows/, trigger it, collect the produced artifacts/logs, and then delete the temporary branch/workflow run to reduce traces. [14][15][16][17][36] - Wormable registry propagation: stolen npm tokens should be validated for publish permissions and whether they bypass 2FA. If they do, enumerate writable packages, download their tarballs, inject a loader such as
setup.mjs, setpreinstallto execute it, bump the patch version, and republish. This turns one CI compromise into downstream auto-execution in other environments. [2][23][24][25]
Practical checks during an assessment
- Review release automation for package-manager hooks added to
package.json, unexpectedbinentries, or version bumps that only modify the release artifact. [20][21] - Check whether CI stores long-lived registry credentials in plaintext files such as
~/.npmrcinstead of using short-lived OIDC or trusted publishing. [23][25] - Verify whether GitHub tokens available in CI can write workflow files or create branches/tags. [14][15][16]
- If a compromised package is suspected, inspect the published tarball and not only the Git repository, because the malicious loader/runtime may exist only in the published artifact. [2][20]
- Hunt for unexpected package-manager execution inside CI such as
npm installinstead ofnpm ci, unexpected Bun downloads/execution, or new workflow artifacts generated from transient branches. [2][17][21][36] - Review GitOps deployment engines as CI/CD targets too. Argo CD-specific enumeration, repo-server abuse, and Redis cache poisoning attacks are covered in Argo CD Security. [33]
More relevant info
Tools & CIS Benchmark
- Chain-bench is an open-source tool for auditing your software supply chain stack for security compliance based on a new CIS Software Supply Chain benchmark. The auditing focuses on the entire SDLC process, where it can reveal risks from code time into deploy time. [28][29]
Top 10 CI/CD Security Risk
Check this article about the top 10 CI/CD risks according to Cider: https://www.cidersecurity.io/top-10-cicd-security-risks/. [4][30]
Labs
- On each platform that you can run locally you will find how to launch it locally so you can configure it as you want to test it
- Gitea + Jenkins lab: https://github.com/cider-security-research/cicd-goat. [31]
Automatic Tools
References
- [1] PPE — Poisoned Pipeline Execution
- [2] The npm Threat Landscape: Attack Surface and Mitigations
- [3] Checkmarx Security Update: April 22, 2026
- [4] CICD-SEC-04: Poisoned Pipeline Execution
- [5] About Version Control
- [6] GitHub Authentication Documentation
- [7] Validating webhook deliveries
- [8] About protected branches
- [9] Workflow syntax for GitHub Actions
- [10] Pipeline as Code with Jenkins
- [11] CI/CD YAML syntax reference
- [12] Pipelines
- [13] Secure use reference
- [14] Automatic token authentication
- [15] Scopes for OAuth apps
- [16] REST API endpoints for GitHub Actions workflows
- [17] REST API endpoints for workflow runs
- [18] Build context
- [19] Breaking out of MCP server hosting
- [20] package.json
- [21] npm scripts
- [22] npm config
- [23] About access tokens
- [24] Requiring 2FA for package publishing and settings modification
- [25] Trusted publishers
- [26] gh auth token
- [27] Git credentials
- [28] chain-bench
- [29] CIS Software Supply Chain Security Guide v1.0
- [30] Top 10 CI/CD Security Risks
- [31] CICD Goat
- [32] Checkov
- [33] Argo CD Security
- [34] Events that trigger workflows
- [35] Using secrets in GitHub Actions
- [36] Workflow artifacts
[!TIP] Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Browse the full HackTricks Training catalog.Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.


