{"id":23912,"date":"2025-03-18T13:38:26","date_gmt":"2025-03-18T09:38:26","guid":{"rendered":"https:\/\/me-en.kaspersky.com\/blog\/malicious-github-action-changed-files\/23912\/"},"modified":"2025-03-18T13:38:26","modified_gmt":"2025-03-18T09:38:26","slug":"malicious-github-action-changed-files","status":"publish","type":"post","link":"https:\/\/me-en.kaspersky.com\/blog\/malicious-github-action-changed-files\/23912\/","title":{"rendered":"Attack on DevOps: secrets leaked via malicious GitHub Action"},"content":{"rendered":"<p>Attacks on open-source mostly start with publishing new malicious packages in repositories. But the attack that occurred on March 14 is in a different league \u2014 attackers compromised the popular GitHub Action tj-actions\/changed-files, which is used in more than 23,000 repositories. The incident was assigned <a href=\"https:\/\/cve.mitre.org\/cgi-bin\/cvename.cgi?name=CVE-2025-30066\" target=\"_blank\" rel=\"nofollow noopener\">CVE-2025-30066<\/a>.\u00a0 All repositories that used the infected changed-files Action are susceptible to this vulnerability. Although the GitHub administration blocked changed-files Action and then rolled it back to a safe version, everyone who used it should conduct an incident response, and the developer community should draw more general lessons from this incident.<\/p>\n<h2>What are GitHub Actions?<\/h2>\n<p><a href=\"https:\/\/docs.github.com\/ru\/actions\" target=\"_blank\" rel=\"nofollow noopener\">GitHub Actions<\/a> are workflow patterns that simplify software development by automating common DevOps tasks. They can be triggered when certain events (such as commits) occur at GitHub. GitHub has a kind of app-store where developers can take a ready-made workflow process and apply it to their repository. To integrate such a ready-made GitHub process into your CI\/CD development pipeline, you only need one line of code.<\/p>\n<h2>changed-files compromise incident<\/h2>\n<p>On March 14, the popular tj-actions\/changed-files GitHub Action \u2014 used to get any changed files from a project \u2014 was infected with malicious code. The attackers modified the process code and updated the version tags to include a malicious commit in all versions of changed-files GitHub Action. This was done on behalf of the Renovate Bot user, but according to current information the bot itself wasn\u2019t compromised; it was just a disguise for an anonymous commit.<\/p>\n<p>The malicious code in changed-files is disguised as the updateFeatures function, which actually runs a malicious Python script and dumps the Runner Worker process memory, then searches it for data that looks like secrets (AWS, Azure and GCP keys, GitHub PAT and NPM tokens, DB accounts, RSA private keys). If something similar is found, it\u2019s written to the repository logs. Both the malicious code and the stolen secrets are written with simple obfuscation \u2014 double base64 encoding. If the logs are publicly available, attackers (and not only the operators of the attack, but anyone!) can freely download and decrypt this data. On March 15, a day after the incident was discovered, GitHub deleted the changed-files process, and the CI\/CD processes based on it may have not functioned. After another eight hours, the process repository was restored in a \u201cclean version\u201d, and now changed-files is working again without surprises.<\/p>\n<h2>Incident Response<\/h2>\n<p>Since logs in public repositories are accessible to outsiders, they\u2019re the most likely to have been affected by the leak. However, in an enterprise environment, relying solely on the assumption that \u201call our repositories are private\u201d is also not a good idea. Companies often have both public and private repositories, and if their CI\/CD pipelines use overlapping secrets, attackers can still use this data to compromise container registries or other resources. Containers or packages built by popular open-source projects can also be compromised in this scenario.<\/p>\n<p>The authors of the ill-fated changed-files <a href=\"https:\/\/github.com\/tj-actions\/changed-files\" target=\"_blank\" rel=\"nofollow noopener\">recommend<\/a> analyzing GitHub logs for March 14 and 15. If unusual data is found in the changed-files subsection, it should be decoded to understand what information may have been leaked. Additionally, it\u2019s worth examining GitHub logs for this period for suspicious IP addresses. All changed-files users are advised to replace secrets that could have been used in the build and leaked during this period. First of all, you should pay attention to repositories with public CI logs, and secondly, to private repositories.<\/p>\n<p>In addition to replacing potentially compromised secrets, it\u2019s recommended to download the logs for subsequent analysis, and then clear their public versions.<\/p>\n<h2>Lessons from the incident<\/h2>\n<p>The complexity and variety of attacks on the supply chain in software development are growing: we\u2019ve already become accustomed to attacks in the form of <a href=\"https:\/\/securelist.com\/two-more-malicious-python-packages-in-the-pypi\/107218\/\" target=\"_blank\" rel=\"nofollow noopener\">malicious repositories<\/a>, infected packages and container images, and we\u2019ve encountered <a href=\"https:\/\/securelist.com\/xz-backdoor-story-part-1\/112354\/\" target=\"_blank\" rel=\"nofollow noopener\">malicious code in test cases<\/a> \u2014 and now in CI\/CD processes. Strict information-security hygiene requirements should extend to the entire life-cycle of an IT project.<\/p>\n<p>In addition to the requirement to strictly select the source code base of your project (open source packages, container images, automation tools), a <a href=\"https:\/\/me-en.kaspersky.com\/enterprise-security\/container-security?icid=me-en_kdailyplacehold_acq_ona_smm__onl_b2b_kasperskydaily_wpplaceholder_______\" target=\"_blank\" rel=\"noopener\">comprehensive container security solution<\/a> and a secrets management system are necessary. Importantly, the requirements for special handling of secrets apply not only to the project\u2019s source code, but also to the development processes. GitHub has a detailed guide on <a href=\"https:\/\/docs.github.com\/en\/actions\/security-for-github-actions\/security-guides\/security-hardening-for-github-actions?learn=getting_started\" target=\"_blank\" rel=\"nofollow noopener\">securely configuring GitHub Actions<\/a> \u2014 the largest section of which is devoted specifically to handling secrets.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to respond to a compromised GitHub changed-files Action incident.<\/p>\n","protected":false},"author":2706,"featured_media":23913,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1318,1916,1917,1486],"tags":[2319,2310,2820,1658,1576,1758,2821,1723],"class_list":{"0":"post-23912","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-business","8":"category-enterprise","9":"category-smb","10":"category-threats","11":"tag-containers","12":"tag-devops","13":"tag-devsecops","14":"tag-github","15":"tag-hybrid-cloud","16":"tag-supply-chain","17":"tag-supply-chain-attacks","18":"tag-supply-chain-attack"},"hreflang":[{"hreflang":"en-ae","url":"https:\/\/me-en.kaspersky.com\/blog\/malicious-github-action-changed-files\/23912\/"},{"hreflang":"en-in","url":"https:\/\/www.kaspersky.co.in\/blog\/malicious-github-action-changed-files\/28672\/"},{"hreflang":"en-gb","url":"https:\/\/www.kaspersky.co.uk\/blog\/malicious-github-action-changed-files\/28789\/"},{"hreflang":"ru","url":"https:\/\/www.kaspersky.ru\/blog\/malicious-github-action-changed-files\/39239\/"},{"hreflang":"x-default","url":"https:\/\/www.kaspersky.com\/blog\/malicious-github-action-changed-files\/53179\/"},{"hreflang":"ru-kz","url":"https:\/\/blog.kaspersky.kz\/malicious-github-action-changed-files\/28945\/"},{"hreflang":"en-au","url":"https:\/\/www.kaspersky.com.au\/blog\/malicious-github-action-changed-files\/34739\/"},{"hreflang":"en-za","url":"https:\/\/www.kaspersky.co.za\/blog\/malicious-github-action-changed-files\/34368\/"}],"acf":[],"banners":"","maintag":{"url":"https:\/\/me-en.kaspersky.com\/blog\/tag\/supply-chain-attack\/","name":"supply-chain attack"},"_links":{"self":[{"href":"https:\/\/me-en.kaspersky.com\/blog\/wp-json\/wp\/v2\/posts\/23912","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/me-en.kaspersky.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/me-en.kaspersky.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/me-en.kaspersky.com\/blog\/wp-json\/wp\/v2\/users\/2706"}],"replies":[{"embeddable":true,"href":"https:\/\/me-en.kaspersky.com\/blog\/wp-json\/wp\/v2\/comments?post=23912"}],"version-history":[{"count":0,"href":"https:\/\/me-en.kaspersky.com\/blog\/wp-json\/wp\/v2\/posts\/23912\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/me-en.kaspersky.com\/blog\/wp-json\/wp\/v2\/media\/23913"}],"wp:attachment":[{"href":"https:\/\/me-en.kaspersky.com\/blog\/wp-json\/wp\/v2\/media?parent=23912"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/me-en.kaspersky.com\/blog\/wp-json\/wp\/v2\/categories?post=23912"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/me-en.kaspersky.com\/blog\/wp-json\/wp\/v2\/tags?post=23912"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}