Uncovering and Responding to the tj-actions Supply Chain Breach

Black Hat USA 2025 · Day 1 · Briefings

Overview

On March 14, 2025, Step Security's automated detection system identified that the widely-used tj-actions/changed-files GitHub Action had been compromised via a chained supply chain attack originating from a pull request vulnerability in an unrelated repository. The malicious "imposter commit" used a memory-dumping technique to harvest CI/CD secrets — including AWS access keys and GitHub tokens — from the build logs of over 23,000 public repositories. The attack exploited GitHub's mutable release tags and a novel "imposter commit" technique that left no visible trace in repository history. ---

Watch on YouTube

Visual summary for Uncovering and Responding to the tj-actions Supply Chain Breach
Visual summary for Uncovering and Responding to the tj-actions Supply Chain Breach

Key moments

  1. 0:03 Discovery: anomalous outbound network call detected, tj-actions compromised in 15 minutes
  2. 2:02 Scale: compromised action used in 23,000+ public repos including GitHub, Meta, Microsoft
  3. 6:00 Root vulnerability: all third-party GitHub Actions share host memory with CI/CD secrets
  4. 7:00 Key weakness: GitHub release tags are mutable, attackers can redirect v44 to malicious commit
  5. 10:00 Detection method: baseline-driven outbound network monitoring caught new gist.githubusercontent.com call
  6. 12:04 Technique: imposter commits in fork repos can be tagged to original repo without existing there
  7. 14:00 Attack payload: memdump.py dumps runner.worker process memory to steal all CI/CD secrets

Uncovering and Responding to the tj-actions Supply Chain Breach

Speakers: Varun Sharma (CEO & Co-founder, Step Security) and Ashish Kurmi (CTO & Co-founder, Step Security)

Conference: Black Hat USA 2025 — August 6-7, 2025, Mandalay Bay, Las Vegas

YouTube: Watch the full talk

Reading time: ~10 minutes

Type: Briefing

TL;DR

On March 14, 2025, Step Security's automated detection system identified that the widely-used tj-actions/changed-files GitHub Action had been compromised via a chained supply chain attack originating from a pull request vulnerability in an unrelated repository. The malicious "imposter commit" used a memory-dumping technique to harvest CI/CD secrets — including AWS access keys and GitHub tokens — from the build logs of over 23,000 public repositories. The attack exploited GitHub's mutable release tags and a novel "imposter commit" technique that left no visible trace in repository history.

Introduction

CI/CD pipeline security has long been treated as a second-class concern relative to application and production environment security. The tj-actions incident changed that calculus permanently. When Varun Sharma and Ashish Kurmi of Step Security discovered on a Friday afternoon in March that tj-actions/changed-files — used by organizations including GitHub, Hugging Face, HashiCorp, Meta, and Microsoft — had been weaponized to steal credentials from thousands of workflow runs, CI/CD supply chain attacks officially moved from theoretical concern to confirmed national security issue.

Within days of discovery, CISA published a cybersecurity advisory urging organizations to remediate. This talk, presented at Black Hat USA 2025, provides the first comprehensive technical postmortem of the entire attack chain: how it was detected, how it worked, how the attacker got in, and what defenders must do differently.

How the Attack Was Detected: Baseline-Driven Monitoring

Detection came not from a signature or known-bad indicator, but from behavioral anomaly detection. Step Security's Harden-Runner product — described by the speakers as "an EDR for CI/CD environments" — continuously monitors outbound network calls from CI/CD runner processes and builds a baseline over repeated workflow runs.

▶ Watch: Detection methodology (08:07)

After more than 2,000 runs of a representative workflow, the baseline showed a consistent set of outbound connections: github.com on every run, and amazonaws.com or hashicorp.com on deployment runs. On March 14, a new endpoint appeared: gist.githubusercontent.com. Because that domain had never appeared in the baseline for that job, the system flagged it immediately.

Further investigation revealed the anomalous connection was being made by the tj-actions/changed-files action, via a curl command downloading a file named memdump.py — a highly suspicious filename. Checking the action's release tags showed that all tags had been updated just three hours earlier to point to the same malicious commit.

The speakers emphasize that this methodology — not the specific tool — is what matters. Organizations can replicate baseline-driven CI/CD monitoring using open-source tools like Wazuh, Falco, or Tetragon, correlating their output with pipeline data to build anomaly detection.

The Imposter Commit Technique

The technical centerpiece of the attack is the "imposter commit." GitHub's API design allows commits from a fork of a repository to be referenced by tags in the original repository, even though those commits do not exist in the original repository's branch history.

▶ Watch: Imposter commit explained (12:08)

The attack flow was:

  1. The attacker created a fork of the tj-actions/changed-files repository.
  2. A malicious commit was pushed to the fork, containing Base64-encoded backdoor code.
  3. The attacker — who had obtained write access to the original repository — updated all release tags (v1 through v44+) to point to this fork commit.
  4. Every workflow run consuming any version of the action now executed the attacker's code.

The malicious imposter commit, when Base64-decoded, performed three steps. First, it downloaded memdump.py from a well-known public GitHub Gist. Second, it executed that script to dump the memory of the runner.worker process — the GitHub Actions process that holds CI/CD secrets in memory while a workflow executes. Third, it exfiltrated the extracted secrets by printing them to standard output (build logs), but cleverly encoded them with double Base64 to bypass GitHub's secret masking, which only detects single-Base64-encoded secrets.

The result: AWS access keys, GitHub tokens, database passwords, and other credentials appeared in plain text in the build logs of every affected workflow run — visible to anyone with repository access.

The Attack Chain: From spotbugs to tj-actions

The compromise of tj-actions/changed-files was not the starting point. It was the end of a three-link supply chain attack.

▶ Watch: Full attack chain timeline (26:09)

The root cause was a pull request vulnerability in the spotbugs/sonar-findbugs repository. This led to the compromise of a Personal Access Token (PAT) belonging to a maintainer who also had write access to the reviewdog GitHub organization — an organization whose membership policy automatically granted write access to any contributor whose PR was merged.

The attackers used the stolen PAT to compromise reviewdog/action-setup, using the same imposter commit technique. When tj-actions/changed-files ran its own CI workflow (which used the tj-actions/eslint-changed-files composite action, which in turn used reviewdog/action-setup), the ReviewDog compromise caused the PAT_TOKEN used in that workflow to be leaked in the build logs. The attackers harvested that token and used it to modify all tags on tj-actions/changed-files.

The ReviewDog compromise went unnoticed for five days because it was only active for two hours on March 11. Security researcher Adnan Khan identified the link on March 17 by examining the build logs from that window and noticing a major release tag pointing to a commit outside the repository.

Why Traditional Security Tools Missed It

The attackers took deliberate steps to evade detection.

▶ Watch: Evasion techniques (28:10)

  • High-reputation domain: The exploit code was downloaded from gist.githubusercontent.com, a GitHub-owned domain that most EDR agents and runtime security tools whitelist unconditionally.
  • No repository traces: Because imposter commits exist in a fork rather than the original repo, browsing any branch in the target repository during the attack would have shown no malicious code.
  • Identity spoofing: The attackers impersonated Renovate Bot — a well-known, trusted automation account — in the imposter commit's author metadata.
  • Clean repository activity: All repository branches and commit histories appeared normal throughout the attack.

The ReviewDog imposter commit went even further — it embedded the exploit code directly in the commit rather than downloading it, eliminating any network connection that could trigger anomaly detection.

Four Concrete Recommendations for Defenders

Sharma and Kurmi close with actionable guidance drawn directly from the incident.

1. Security monitoring for CI/CD runners. Most organizations have EDR on endpoints and monitoring in production, but CI/CD runners have zero coverage. Implement baseline-driven monitoring using Wazuh, Falco, or Tetragon to track outbound network calls, process events, and file write events, and alert on deviations.

2. Implement an action allowlist. GitHub's marketplace has over 25,000 actions. Organizations should define a policy governing which actions can be used, with a vetting process before any new action is approved. This limits blast radius when any one action is compromised.

3. Pin actions to immutable commit SHAs. Organizations that had already pinned tj-actions/changed-files to a specific commit SHA — rather than a mutable tag like v44 — were not affected by the tag-reassignment attack. Pinning is a simple configuration change that eliminates this entire class of risk.

4. Prepare an incident response plan for compromised actions. When the incident occurred, identifying affected workflows, correlating run timestamps with the compromise window, finding leaked credentials in build logs, and rotating them was an enormous manual effort. Organizations should pre-build runbooks so they can act in minutes rather than hours when the next incident occurs.

Notable Quotes

"In just a couple of hours, the attackers had harvested secrets from thousands of workflow runs. Let that sink in. Thousands of cloud credentials, access keys, database passwords — all exposed in the open for anyone to steal and abuse."

— Varun Sharma [[▶ 20:08]](https://www.youtube.com/watch?v=-BCngzJC1Rc&t=1208s)

"The attack blueprint is now public. So the next one may not just dump secrets in build logs. The next one may not just compromise two actions — and it may already be in your pipeline."

— Varun Sharma [[▶ 32:11]](https://www.youtube.com/watch?v=-BCngzJC1Rc&t=1931s)

"GitHub tags by default are mutable — think of them as signposts that can be moved. Today, v44 is pointing to a legitimate commit, but tomorrow, an attacker can point it to wherever they want."

— Ashish Kurmi [[▶ 06:06]](https://www.youtube.com/watch?v=-BCngzJC1Rc&t=366s)

"The terrifying brilliance of this attack is that traditional security tools wouldn't flag any of this as suspicious."

— Varun Sharma [[▶ 30:11]](https://www.youtube.com/watch?v=-BCngzJC1Rc&t=1811s)

Key Takeaways

  • Mutable release tags are a fundamental CI/CD risk. Any workflow pinning to a tag name (e.g., v4) rather than a commit SHA can be silently redirected to malicious code without any alert or visible repository change.
  • Imposter commits are a novel attack primitive. GitHub's shared object store across forks enables commits in forks to be referenced from parent repositories — a design property that can be weaponized without leaving traces in branch history.
  • CI/CD runners need security monitoring. The only reason this attack was caught was behavioral anomaly detection on outbound network traffic. Without that, thousands of additional secrets would have been exposed.
  • Supply chain attacks chain together. The tj-actions breach started with a PR vulnerability three repositories removed from the eventual target. Defense requires visibility into the full dependency graph, not just direct dependencies.
  • Incident response plans for third-party action compromise are essential. The remediation effort post-discovery was enormous because organizations had to manually trace affected workflows, build logs, and credentials. Pre-built runbooks would have dramatically reduced response time.

Slides PDF not available for this talk.

Reviews

Dr. Zero (Offensive Security Researcher) — STRONG ACCEPT

A real-world supply chain incident, detected in production, dissected with forensic precision, and turned into actionable guidance. The imposter commit technique is a legitimate novel attack primitive, and the baseline-driven detection story validates the methodology cleanly. Step Security had skin in the game here — this isn't academic retrospective.

Heather Calloway (CISO) — MUST SEE

The tj-actions supply chain breach is a masterclass in how CI/CD pipeline security was treated as a second-class concern until it wasn't. Mutable release tags, imposter commits leaving no repository traces, credential harvesting from 23,000 public repositories — and the entire attack chain traced to a pull request vulnerability three repositories removed from the eventual target.

→ Top-rated talks at Black Hat USA 2025

All talks from Black Hat USA 2025