Kuboid
Open Luck·Kuboid.in
Security BSides2025
Open in YouTube ↗

Playing Peekaboo with Runtime in CI/CD Pipelines

Security BSides London141 views42:47about 1 month ago

This talk demonstrates how attackers can exploit self-hosted build servers in CI/CD pipelines to achieve persistence and lateral movement. By scheduling malicious jobs, an attacker can execute arbitrary code, exfiltrate environment variables, and compromise the build environment. The presentation highlights the risks of shared build infrastructure and the importance of implementing strict network controls and isolation between pipeline stages. The speaker also discusses the dangers of blindly trusting third-party CI/CD templates and extensions.

How Self-Hosted Build Servers Are Quietly Sabotaging Your CI/CD Security

TLDR: Self-hosted build servers in CI/CD pipelines often lack the rigorous isolation of cloud-managed runners, creating a persistent attack surface for lateral movement and privilege escalation. By scheduling malicious jobs, an attacker can execute arbitrary code, exfiltrate environment variables, and compromise the entire build environment. Security teams must treat these build nodes as production assets and implement strict network egress controls to prevent unauthorized data exfiltration.

Modern CI/CD pipelines are often treated as "magic" infrastructure where code goes in and artifacts come out. Security teams frequently focus on the application code itself, but the underlying build infrastructure—specifically self-hosted runners—is often left in a state of benign neglect. When you run your own build servers, you are essentially running a persistent, high-privilege execution environment that is often shared across multiple projects or teams. This is a massive blind spot.

The Persistence Problem in Self-Hosted Runners

The fundamental issue with self-hosted build servers is that they are not ephemeral. Unlike cloud-managed runners that spin up, execute a job, and vanish, a self-hosted runner is a persistent machine or container that sits waiting for the next job. If an attacker can schedule a job on that runner, they gain a foothold on a machine that likely has access to internal networks, secrets, and source code repositories.

During a recent engagement, it became clear that many organizations assume their CI/CD platform provides inherent isolation between jobs. This is a dangerous assumption. If you are using a self-hosted runner, the environment is only as secure as the last job that ran on it. If a previous job left behind a malicious script or a persistent cron job, the next job—even one from a different, "trusted" project—will execute in that compromised environment.

Exploiting the Build Environment

The attack flow is straightforward but devastating. An attacker with access to a repository can modify the pipeline configuration file to include a malicious step. Because the build server is already authenticated to the CI/CD platform, the attacker does not need to bypass external authentication. They are already inside the perimeter.

Consider a scenario where an attacker adds a simple task to a yaml pipeline file:

- script: |
    echo "Running reconnaissance..."
    (crontab -l 2>/dev/null; echo "* * * * * /tmp/exfil.sh") | crontab -
    cat /etc/environment > /tmp/env_dump

This command installs a persistent cron job that executes every minute. Even if the original pipeline job finishes and the build server reports success, the malicious cron job remains. The next time a legitimate developer pushes code, their build will run on a server that is actively exfiltrating environment variables or source code to an attacker-controlled endpoint.

The Hidden Risk of Trusted Templates

Many teams rely on third-party templates and extensions to simplify their pipeline configurations. This is a classic supply chain risk. If you pull a template from a public repository, you are essentially running code written by someone else with the same privileges as your own build process.

The CVE-2025-30066 vulnerability serves as a stark reminder of this reality. Attackers can compromise popular, widely used GitHub Actions to inject malicious payloads into downstream pipelines. When you use these actions, you are often implicitly trusting the maintainer's security practices. If that maintainer's account is compromised, your pipeline is compromised.

To mitigate this, you must pin your dependencies to specific commit hashes rather than tags or branches. If you are using Checkov to scan your infrastructure as code, ensure you are also scanning your pipeline definitions for insecure configurations, such as the use of unpinned actions or overly permissive shell commands.

Hardening Your Build Infrastructure

Defending build servers requires a shift in mindset. You cannot treat them as disposable utilities. They are production infrastructure.

First, implement strict network egress controls. A build server should only be able to communicate with the specific registries and services it needs to function. If your build server is reaching out to random IP addresses on the internet, that is a red flag. Use an allow-list model to restrict outbound traffic to known, trusted endpoints.

Second, enforce isolation. If possible, use ephemeral, containerized runners that are destroyed immediately after a job completes. If you must use persistent machines, ensure they are wiped or re-imaged between jobs. This is OWASP A01:2021-Broken Access Control in action; if you cannot guarantee the state of your runner, you have lost control over who can access your secrets.

Finally, monitor your build logs for anomalous behavior. Look for unexpected network connections, the creation of new files in /tmp or /var/tmp, and any modifications to system-level configuration files. If your build server is suddenly trying to scan your internal network, you have already been compromised.

The convenience of self-hosted runners is undeniable, but it comes at a cost. If you are not prepared to manage the security of that infrastructure with the same rigor you apply to your production servers, you are leaving the door wide open for anyone who can commit code to your repository. Stop treating your pipelines as a black box and start auditing what is actually running on your build nodes.

Talk Type
talk
Difficulty
intermediate
Has Demo Has Code Tool Released


BSides London 2025 Track 2

8 talks · 2025
Browse conference →
Premium Security Audit

We break your app before they do.

Professional penetration testing and vulnerability assessments by the Kuboid Secure Layer team. Securing your infrastructure at every layer.

Get in Touch
Official Security Partner
kuboid.in