Potential injected malicious code into files referenced by the pipeline configuration file

ID

indirect_poisoned_pipeline_execution

Severity

critical

Family

CI/ CD Security

Tags

cicd-sec-04, cicd-security, infrastructure, reachable, security

Description

Poisoned Pipeline Execution (PPE) risks refer to the ability of an attacker with access to source control systems - and without access to the build environment, to manipulate the build process by injecting malicious code/commands into the build pipeline configuration, essentially ‘poisoning’ the pipeline and running malicious code as part of the build process.

There are three types of PPE:

  • Direct PPE (D-PPE): The attacker modifies the CI config file in a repository they have access to, either by pushing the change directly to an unprotected remote branch on the repo, or by submitting a PR with the change from a branch or a fork

  • Indirect PPE (I-PPE): The attacker cannot modify the pipeline itself, but he/ she may gain control of a script which is executed in the pipeline.

  • Public-PPE (3PE): The CI pipeline of a public repository runs unreviewed code suggested by anonymous users.

This detector focuses on detecting Indirect PPE. Vulnerable pipelines are those that:

  • Use secrets.

  • Perform a checkout of the PR code.

  • Invoke other repository scripts or files.

Security

In a successful PPE attack, attackers execute malicious unreviewed code in the CI. This provides the attacker with the same abilities and level of access as the build job, including:

  • Access to any secret available to the CI job, such as secrets.

  • Access to external assets the job node has permissions to, such as files stored in the node’s file system, or credentials to a cloud environment accessible through the underlying host.

  • Ability to ship code and artifacts further down the pipeline, in the guise of legitimate code built by the build process.

  • Ability to access additional hosts and assets in the network/environment of the job node.

Mitigation / Fix

  • Don’t check out the Pull Request code in the pipeline.

  • Keep the pipeline and the invoked scripts/ files into a separate repository.