On March 12, 2025 a malicious commit was introduced into the GitHub Action tj-actions/changed-files that injected base64‑encoded Node.js which downloaded Python scripts to scan GitHub Runner memory for credentials. Affected projects should rotate secrets immediately and deploy runtime detection (for example Falco or Sysdig Secure) to detect memory scanning and exfiltration attempts. #tj-actions_changed-files #CVE-2025-30066
Keypoints
- CVE-2025-30066 has been assigned to the compromise of the tj-actions/changed-files GitHub Action.
- The attacker injected a Node.js function with base64-encoded payloads that download additional Python code to perform memory scanning.
- The Python payload scanned the GitHub Runner (Runner.worker) memory for credentials using regex and either printed them to build logs or exfiltrated them.
- Public repositories that ran the compromised action between 2025-03-12 00:00 and 2025-03-15 12:00 UTC are at high risk of exposure; private repos are also at risk.
- Exfiltration paths included posting stolen data to a GitHub Gist (https://gist.githubusercontent.com/<attacker_id>) in some variants.
- Recommended mitigations: rotate all potentially exposed secrets, implement runtime detection (Falco, Sysdig Secure), and replace the compromised action with alternatives.
MITRE Techniques
- [T1059.007] Command and Scripting Interpreter: JavaScript – The attacker injected a Node.js function containing base64-encoded instructions. (‘The attacker injected a Node.js function containing base64-encoded instructions.’)
- [T1027] Obfuscated Files or Information – The malicious script used base64 encoding to hide its payload. (‘The malicious script used base64 encoding to hide its payload.’)
- [T1204.002] User Execution: Malicious File – The GitHub Action executed the compromised script as part of a CI/CD workflow. (‘The GitHub Action executed the compromised script as part of a CI/CD workflow.’)
- [T1055.012] Process Injection: Process Memory Injection – The Python script scanned the memory of the GitHub Runner (Runner.worker) for credentials. (‘The Python script identifies the GitHub Runner’s process (specifically the “Runner.worker” process), opens its memory mappings, and searches for sensitive credentials using regular expressions.’)
- [T1552.001] Unsecured Credentials: Credentials in Files – Extracted secrets from GitHub Runner memory were output to build logs. (‘Extracted secrets from GitHub Runner memory and stored them in logs.’)
- [T1567.002] Exfiltration Over Web Service: Exfiltration to Code Repositories – Some attack variants exfiltrated credentials via a POST request to a GitHub Gist. (‘Some versions of the attack exfiltrated credentials via a POST request to a GitHub Gist.’)
Indicators of Compromise
- [Repository] Compromised action – https://github.com/tj-actions/changed-files (compromised repository/action; no longer available)
- [Exfiltration URL] Gist used for exfiltration – https://gist.githubusercontent.com/<attacker_id> (used to store/stage stolen credentials)
- [Payload artifacts] Malicious payloads and scripts – base64-encoded Node.js payload, Python memory-scan script downloaded from a Gist
- [Process name] Targeted process – Runner.worker (GitHub Runner process whose memory was scanned)
- [Logs] Credential exposure location – GitHub Action build logs (credentials printed in logs in some variants)