---
title: "The tj-actions/changed-files compromise: what it did, and why Kilobat’s part is small"
url: "https://kilobat.app/incidents/tj-actions-changed-files"
description: "How a compromised GitHub Action printed CI secrets into public workflow logs in March 2025, why it barely touched developers’ Macs, and what to check."
---

Incident · GitHub Action compromise

# The tj-actions/changed-files compromise: what it did, and why Kilobat’s part is small

On 14 and 15 March 2025, a GitHub Action used in more than 23,000 repositories dumped the secrets of every workflow that ran it into the workflow’s own log. This all happened on CI runners, not on developers’ Macs, so this page is mostly about what to check in your repositories, and it says plainly how little Kilobat could have seen.

When: 14–15 March 2025 · Sources checked: 1 November 2026

## In short

- [Protection](https://kilobat.app/mac-malware-blocker): Wouldn’t help

  The attack ran on GitHub’s runners. Its one download came from gist.githubusercontent.com, and nothing was sent to an outside server at all.
- [Agent guard](https://kilobat.app/mac-malware-blocker): Wouldn’t help

  No agent was involved, and the secrets left through log output, not through a connection.
- [Agent network log](https://kilobat.app/ai-coding-agents): Wouldn’t help

  Workflows run with `act` run in Docker, whose traffic Kilobat can’t attribute to an agent.
- [App traffic](https://kilobat.app/mac-bandwidth-monitor): Limited

  Only on a Mac that runs workflows itself, as a self-hosted runner: the app list would show the runner’s connections, including the gist download. Nothing would be blocked.

## What happened

[GitHub’s advisory](https://github.com/advisories/GHSA-mrrh-fwg8-r2c3) for CVE-2025-30066 says the attacker changed most of the action’s existing version tags, from `v1.0.0` on, to point at one malicious commit, `0e58ed8`. Every workflow that used the action by tag got that code on its next run. It downloaded a Python script from a GitHub gist and ran it with `sudo`; the script found GitHub’s `Runner.Worker` process, read its memory, picked out the values marked as secrets and printed them, base64-encoded twice, into the log. Workflows pinned to a full commit hash were not affected.

On a public repository, workflow logs are public, so the secrets were readable by anyone. [Wiz](https://www.wiz.io/blog/github-action-tj-actions-changed-files-supply-chain-attack-cve-2025-30066) found dozens of repositories with exposed secrets; the risk to private repositories was much smaller. [StepSecurity](https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised) spotted it because its runner monitoring flagged an unexpected call to `gist.githubusercontent.com`.

The tj-actions maintainers said a personal access token of their bot account had been compromised. [Unit 42](https://unit42.paloaltonetworks.com/github-actions-supply-chain-attack/) traced the chain further back: a workflow pushed to the SpotBugs repository leaked a maintainer’s token, which had write access to `reviewdog/action-setup`; that action was compromised in turn (CVE-2025-30154), and a tj-actions workflow that used it leaked the bot’s token. Unit 42 found the first target was a Coinbase open-source project, where the attacker didn’t manage to use the secrets.

## Timeline

1. November 2024

   Unit 42 dates the attacker’s first steps to this month.
2. 11 Mar 2025

   A workflow pushed to SpotBugs leaks a maintainer’s token; `reviewdog/action-setup@v1` is compromised between 18:42 and 20:31 UTC (Unit 42, CISA).
3. 14 Mar, about 16:00 UTC

   The action’s tags point at the malicious commit; StepSecurity detects it and confirms most versions are affected within the hour.
4. 15 Mar 2025

   The gist is deleted; GitHub takes the action down and restores it cleaned (14:00 and 22:00 UTC, by StepSecurity’s timeline). Version 46.0.1 is the fix.
5. 18 Mar 2025

   StepSecurity finds several reviewdog actions also compromised; CISA publishes its alert.
6. 26 Mar 2025

   CISA’s alert notes both CVEs in its Known Exploited Vulnerabilities catalogue.
7. 2 Apr 2025

   Unit 42 publishes the SpotBugs and Coinbase steps that led to the compromise.

## What it looked like on the network

Everything happened on CI runners. The malicious step made one outbound request, to `gist.githubusercontent.com`, for `memdump.py`; the rest was local to the runner. The secrets never went to an attacker’s server: they were written into the log, and GitHub served that log to whoever looked.

The published script finds the runner process through Linux’s `/proc` file system, and the sources describe its effect on Linux runners. The stolen tokens were then usable from anywhere, against GitHub and the other services they belonged to.

## Indicators

As the sources document them. Domains are text, never links, and are defanged (`[.]`) where the source defangs them. Most of this infrastructure is long gone: indicators help you check old logs, files and accounts, not block today’s campaigns.

| Indicator | Type | Where it shows | Note |
|---|---|---|---|
| `0e58ed8671d6b60d0890c21b07f8835ace038e67` | Commit | tj-actions/changed-files | The commit the rewritten tags pointed to. |
| `gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py` | URL | CI runner | The memory-dumping script. Deleted on 15 March 2025. |
| `A double-base64 string in the changed-files step’s log` | Log output | Workflow logs | Present if the payload ran. Decoded, it holds the run’s secrets. |
| `reviewdog/action-setup@v1, 11 March 2025, 18:42–20:31 UTC` | Action, time window | Workflows | CVE-2025-30154; also affected other reviewdog actions that use it. |
| `tj-actions/changed-files, 12 March 00:00 to 15 March 12:00 UTC` | Action, time window | Workflows | The window CISA asks you to audit. |

## What Kilobat would have shown or blocked

- **[App traffic](https://kilobat.app/mac-bandwidth-monitor).** If your Mac is a self-hosted runner and ran the action, Kilobat’s app list would have shown the runner’s processes connecting to `gist.githubusercontent.com`. That host isn’t on any threat list, and shouldn’t be: gists are used legitimately all the time.
- **[Agent network log](https://kilobat.app/ai-coding-agents).** Running a workflow on the Mac with `act`, even from an AI agent, puts the steps inside Docker containers. Their connections leave through Docker’s own process, which Kilobat can’t attribute to the agent, so the agent network log wouldn’t list them.
- **[Protection](https://kilobat.app/mac-malware-blocker).** Protection had nothing to act on. If a token from a leaked log was later used against you, that use happened from the attacker’s machines, against GitHub.

## Where Kilobat wouldn’t have helped

- The compromise, the secret dump and the leak all happened in GitHub Actions. A tool on your Mac can’t see someone else’s runner.
- Secrets left through log output that GitHub served normally, not through a connection anyone could block.
- The script was fetched from a GitHub-hosted gist, a host any network filter has to allow.
- Docker containers and VMs on a Mac are opaque to Kilobat’s per-process view.

## Check your Mac now

1. List the workflows in a repository that use the affected actions.

   ```
   grep -rnE "tj-actions/changed-files|tj-actions/eslint-changed-files|reviewdog/action-" .github/workflows
   ```
2. Or search all your repositories on GitHub at once.

   ```
   gh search code "tj-actions/changed-files" --owner YOUR-ACCOUNT-OR-ORG
   ```
3. For runs between 12 and 15 March 2025, open the changed-files step’s log and look for a long string that decodes twice. If you find one, every secret that workflow could read is exposed.

   ```
   echo 'PASTE-THE-STRING' | base64 -d | base64 -d
   ```
4. Rotate those secrets, then download the affected logs for your records and delete the runs, so the secrets stop being readable.
5. Find actions pinned by tag rather than by commit. Pin them to a full commit hash, as GitHub recommends.

   ```
   grep -rnE "uses: *[^ ]+@(v[0-9][^ ]*|main|master) *$" .github/workflows
   ```
6. If a token you use on your Mac was stored as a repository secret, revoke it under **Settings › Developer settings › Personal access tokens**, and check which account the GitHub CLI is signed in with.

   ```
   gh auth status
   ```

## Sources

- [GitHub Advisory Database: GHSA-mrrh-fwg8-r2c3, CVE-2025-30066](https://github.com/advisories/GHSA-mrrh-fwg8-r2c3)
- [CISA: Supply chain compromise of third-party tj-actions/changed-files (CVE-2025-30066) and reviewdog/action-setup@v1 (CVE-2025-30154)](https://www.cisa.gov/news-events/alerts/2025/03/18/supply-chain-compromise-third-party-tj-actionschanged-files-cve-2025-30066-and-reviewdogaction)
- [StepSecurity: Harden-Runner detection, tj-actions/changed-files action is compromised](https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised)
- [Wiz: GitHub Action tj-actions/changed-files supply chain attack](https://www.wiz.io/blog/github-action-tj-actions-changed-files-supply-chain-attack-cve-2025-30066)
- [Unit 42: GitHub Actions supply chain attack, a targeted attack on Coinbase expanded to the widespread tj-actions/changed-files incident](https://unit42.paloaltonetworks.com/github-actions-supply-chain-attack/)

Checked on 1 November 2026.

## See what your agents and apps connect to

Kilobat is a Mac menu-bar app that names the app, process and agent behind every connection, keeps them away from known-bad hosts, and logs what each agent session reached.

[Download for Mac ↓](https://kilobat.app/downloads/Kilobat-1.31.1.dmg?via=site)

```
brew install seifip/kilobat/kilobat
```

## More incidents

- [The “Shai-Hulud” npm worm](https://kilobat.app/incidents/shai-hulud-npm-worm): A worm that stole developers’ tokens, republished itself with them, and leaked secrets through GitHub and webhook.site.
- [Nx “s1ngularity”](https://kilobat.app/incidents/nx-s1ngularity): Malicious Nx versions ran installed AI CLIs to find secrets, then published them to a new repository in the victim’s GitHub account.
- [All incidents](https://kilobat.app/incidents): Every case study, with what Kilobat would and wouldn’t have done.
