By clicking “Accept”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.
18px_cookie
e-remove

OWASP OSS Risk 2: Compromise of Legitimate Package

OWASP OSS Risk 2: Explore the compromise of legitimate open-source packages, with an in-depth case study of the tj-actions/changed-files GitHub Action supply chain attack.

OWASP OSS Risk 2: Explore the compromise of legitimate open-source packages, with an in-depth case study of the tj-actions/changed-files GitHub Action supply chain attack.

OWASP OSS Risk 2: Explore the compromise of legitimate open-source packages, with an in-depth case study of the tj-actions/changed-files GitHub Action supply chain attack.

Written by
A photo of Camilla Odlund — Software Infrastructure and Analytics at Endor Labs.
Camilla Odlund
Published on
March 25, 2025

OWASP OSS Risk 2: Explore the compromise of legitimate open-source packages, with an in-depth case study of the tj-actions/changed-files GitHub Action supply chain attack.

OWASP OSS Risk 2: Explore the compromise of legitimate open-source packages, with an in-depth case study of the tj-actions/changed-files GitHub Action supply chain attack.

This article is part of a 10-part series on the Top 10 OSS Risks:

  • OSS-RISK-1 Known Vulnerabilities
  • OSS-RISK-2 Compromise of Legitimate Package (this article)
  • OSS-RISK-3 Name Confusion Attacks (coming soon)
  • OSS-RISK-4 Unmaintained Software (coming soon)
  • OSS-RISK-5 Outdated Software (coming soon)
  • OSS-RISK-6 Untracked Dependencies (coming soon)
  • OSS-RISK-7 License Risk (coming soon)
  • OSS-RISK-8 Immature Software (coming soon)
  • OSS-RISK-9 Unapproved Change (Mutable) (coming soon)

OSS-RISK-10 Under/Over-Sized Dependency (coming soon)

The Top 10 Risks for Open Source, developed by the Station 9 research team at Endor Labs, is an OWASP incubator project. A set of critical risks to applications leveraging open source software (OSS) dependencies, the list includes two categories of risks:

  • Security risks can result in the compromise of system or data confidentiality, integrity, or availability.
  • Operational risks can endanger software reliability or increase the efforts and investments required to develop, maintain, or operate a software solution.

In this 10-part series we explore each risk in depth, including the relevance of each risk and how you can factor them into your security programs. Below we take a closer look at the second risk: Compromise of Legitimate Package

Risk Category: Security

What is a Legitimate Package?

Given that open-source software (OSS) is estimated to be present in 70-90% of applications, it plays a crucial role in modern development. This vast ecosystem, valued at an estimated $8.8 trillion [1], offers developers free access to powerful tools and libraries, accelerating innovation and reducing costs. By leveraging OSS, teams can build more efficiently, avoid reinventing the wheel, and benefit from collective expertise. However, integrating open-source software also comes with risks—especially the potential compromise of legitimate packages, a growing concern in today's software supply chain.

A legitimate package is a reusable software component that is widely recognized as trustworthy, maintained by reputable developers or organizations, and distributed through official channels like npm, PyPI, or Maven Central. These packages are usually open-source, and supported by active maintenance, documentation, and regular version updates. With proper licensing and widespread adoption by trusted projects, legitimate packages are essential building blocks for modern software development, saving software companies a lot of time and money. 

Developers integrate these legitimate packages as dependencies using package managers, often pinning (locking) versions or setting version ranges to ensure stability. Package upgrades are routine, driven by new features, performance enhancements, or critical security patches.

What is a Compromise of a Legitimate Package? Trusting the Source, but not the Delivery

As opposed to the first OWASP OSS Risk, Known Vulnerabilities, which is about publicly disclosed security bugs in the source code, an increasingly common attack vector is to compromise a legitimate package somewhere between you and the trusted maintainer. It’s like if you order takeout from your favorite restaurant: you trust the chef, but what about the DoorDasher?

In this type of attack, attackers compromise resources that are part of an existing legitimate project or of the distribution infrastructure in order to inject malicious code into a component, e.g., through hijacking the accounts of legitimate project maintainers, exploiting vulnerabilities in package repositories, or becoming maintainers themselves.

Compromised packages can then execute malicious code on developer or end-user systems, jeopardizing the confidentiality, integrity, and availability of systems and the data they process. They also enable attackers to move laterally across connected systems and services, amplifying the potential damage to an organization's infrastructure. 

How are Legitimate Packages Compromised?

Bad actors can compromise legitimate packages from the point of development all the way to downloading. Below, we take a closer look at three critical attack vectors that highlight the complexity and potential consequences of such compromises (bear with me, there are a lot of them!), followed by a case study of last week’s GitHub Action tj-actions/changed-files supply chain attack.

  1. Development Stage: Inject malicious code into legitimate package source code
  2. Build Stage: Inject malicious code during the build of legitimate package
  3. Publish/Download Stage: Distribute malicious version of legitimate package

1. Development Stage: Inject Malicious Code into Legitimate Package Source Code

Malicious code is injected into the source code of a trusted project so that downstream users unknowingly incorporate harmful elements. Attackers employ three specific techniques: Hypocrite merge request, contribute as maintainer, and tampering with the version control system.

Hypocrite Merge Request

Attackers sneak in malicious code by submitting seemingly beneficial contributions to a project, such as new features, tests, or documentation. The contributions often target areas subjected to less rigorous scrutiny and sometimes the malicious code is obfuscated by splitting it up into multiple commits or by exploiting rendering weaknesses in the user interface of the tools used for manual code reviews. Once accepted, the malicious code—whether a backdoor or an intentional vulnerability—propagates to all users of the package. Examples:

Contribute as Maintainer

Attackers gain maintainer-level access to a project, enabling them to push malicious changes directly. This access can be obtained through various methods:

Tamper with Version Control System

Attackers exploit vulnerabilities or misconfigurations in version control systems, or gain access via a compromised administrator account, to insert malicious code. While many projects use version control services like GitHub, some still manage their own systems, making them potential targets. Example: CVE-2018-17456: Remote code execution via a malicious .gitmodules file

2. Build Stage: Inject Malicious Code During the Build of Legitimate Package

Rather than targeting source code, attackers may compromise the build process, resulting in infected binaries that are distributed to end-users. Techniques include: Run malicious builds, tampering with build jobs as a maintainer, and tampering with an exposed build system.

Run Malicious Build

In environments where build systems share resources (e.g., plugins or caches), attackers can introduce malicious builds to contaminate shared resources. Subsequent builds by legitimate projects unknowingly execute or incorporate the malicious elements. Example: The Octopus Scanner Malware: Attacking the open source supply chain 

Tamper with Build Job as Maintainer

Attackers impersonate maintainers or exploit weak access controls to modify build job definitions (see “Contribute as Maintainer” above). By injecting malicious configurations or code, they ensure compromised binaries are produced and distributed.

Tamper with Exposed Build System

Build systems accessible online can be exploited via vulnerabilities, weak configurations, or compromised administrator accounts. Attackers may manipulate build processes or artifacts, resulting in malicious binaries distributed through trusted channels. Example: ATT&CK T1190: Exploit Public-Facing Application 

3. Publish/Download Stage: Distribute Malicious Version of Legitimate Package

By replacing legitimate packages with malicious versions, attackers trick developers into downloading and using infected code. Common techniques include: Distributing as a package maintainer, injecting into the hosting system, dangling references, masking legitimate packages, and preventing updates to non-vulnerable versions.

Distribute as Package Maintainer

Attackers gain access to a package maintainer account (see “Contribute as Maintainer” above) and with access to the deployment workflows of a project, they upload new malicious versions of existing packages to official distribution channels. Example: Malicious code in the PureScript npm installer

Inject into the Hosting System

Attackers gain access to the hosting system via vulnerabilities, weak configurations, or compromised administrator accounts and bypass standard deployment processes to tamper with existing binaries on distribution platforms (e.g., npm, PyPI, or CDNs). By altering files directly in hosting systems, they can compromise all downloads of any package hosted on that registry. Example: Beware of hacked ISOs if you downloaded Linux Mint on February 20th! 

Dangling Reference

When a package is deprecated, removed, or renamed, attackers can reintroduce it under the same name but with malicious content. Users with lingering references to the old package inadvertently adopt the compromised version. Example: Repo Jacking: Exploiting the Dependency Supply Chain

Mask Legitimate Package

Attackers manipulate the resolution process for package URLs through techniques like DNS cache poisoning, Man-in-the-Middle attacks, or tampering with dependency resolution mechanisms. Users attempting to download legitimate packages are redirected to malicious versions. The infamous dependency confusion attack falls into this category. Example: Dependency Confusion: How I Hacked Into Apple, Microsoft and Dozens of Other Companies

Prevent Update to Non-Vulnerable Version

Attackers forge metadata or replay signed metadata to block updates, keeping users reliant on vulnerable versions. Techniques include introducing unsatisfiable dependencies or manipulating package metadata.

Case Study: The GitHub Action tj-actions/changed-files Supply Chain Attack

Overview

GitHub Actions are used in CI/CD workflows to automate tasks such as testing, building, and deployment. As such, they often have access to sensitive information such as repository secrets, API keys, and deployment credentials, making them a valuable target for supply chain attacks.

On March 14, 2025, the popular open-source GitHub action tj-actions/changed-files was compromised via several of the attack vectors described above, potentially impacting over 23,000 repositories [2][3]. The incident has been assigned CVE-2025-30066 (tj-actions) and CVE-2025-30154 (reviewdog).

Attackers used a compromised personal access token (PAT) to push a malicious commit disguised as coming from the automation tool renovatebot to the tj-actions/changed-files GitHub repository, and then changed all tags to point to that commit. This code change caused secrets and configuration values to be printed to the GitHub action logs for all projects using the action not pinned to a specific commit SHA.

Learn more in GitHub Action tj-actions/changed-files supply chain attack: what you need to know.

Attack Vectors

The investigation is still ongoing but, as far as we can tell [4] [5] [6] [7] [8] [9] [10], here is the likely step-by-step sequence of actions, and corresponding attack vectors, performed by the attackers:

Step Action Attack Vector
1 Gain write access to reviewdog/action-setup GitHub action (used by tj-actions/eslint-changed-files which is in turn used by tj-actions/changed-files).
This was most likely achieved through an automated invitation, but it is also possible that they compromised an existing maintainer account.
Contribute as a Maintainer—Take-over Legitimate Account, Become a Maintainer
2 Add a malicious commit with user name set to look like the review-dog bot account for the reviewdog/action-setup GitHub action.
The malicious code dumps the workflow secrets for any CI job running it to the logs.
Contribute as a Maintainer—Take-over Legitimate Account, Become a Maintainer
3 Publish a new tag for reviewdog/action-setup@v1 pointing to the forked version. Mask Legitimate Package—Abuse Dependency Resolution Mechanism
See also OSS-RISK-9 Unapproved Change (Mutable)
4 Wait for tj-actions/changed-files to run tj-actions/eslint-changed-files and retrieve the tj-actions PAT from the logs. Run malicious build
5 Use tj-actions PAT to push a malicious commit to tj-actions/changed-files. Contribute as Maintainer—Take-over Legitimate Account
6 Use PAT to update all tags to point to the commit. Contribute as Maintainer—Take-over Legitimate Account
See also OSS-RISK-9 Unapproved Change (Mutable)
7 Wait for the real target(s) of the attack to run tj-actions/changed-files and retrieve their secrets from the logs. Run malicious build
8 Use their secret(s) maliciously, for example by publishing a malicious container using the maintainer’s DockerHub credentials
(see diagram in GitHub Action tj-actions/changed-files supply chain attack: what you need to know for more potential uses)
Depends on the secrets leaked. For example, Distribute as Package Maintainer

Summary

The tj-actions/changed-files supply chain attack highlights the risks of compromised credentials and dependency hijacking in CI/CD workflows. By leveraging a chain of exploits—including a malicious commit, a hijacked contributor account, and a manipulated Git tag—attackers could have exfiltrated thousands of credentials if the attack wasn’t discovered so quickly. This incident underscores the importance of pinning dependencies to specific commit SHAs, monitoring for suspicious activity, and securing contributor accounts to mitigate similar threats in the future.

How to Dodge the Bullet: Protecting Against Compromise of Legitimate Packages

Using open-source software comes with inherent risks, including the potential compromise of legitimate packages. To mitigate this threat, implement the following proactive security controls.

For more detailed safeguards for each attack vector discussed here, visit here.

General Security Controls Against Package Subversion

  • Audit and Remove Unused Dependencies:
    • Regularly audit projects to identify and remove unnecessary dependencies, reducing the likelihood of using compromised packages.
  • Version Pinning and Lockfiles:
    • Use lockfiles (package-lock.json, yarn.lock, poetry.lock) to maintain precise package versions.
    • Leverage integrity checks within lockfiles to quickly detect if a package has been maliciously modified.
  • Build Dependencies from Source:
    • Build critical dependencies from their source or maintain internal forks to verify and control all code changes explicitly.
  • Establish an Internal Package Mirror:
    • Use internal package registries to mirror, vet, and control the exact versions of packages your organization trusts.
  • Integrate regular malware and vulnerability scans into your development pipeline:
    • There is an obvious trade off between using version pinning and automatically updating to the latest version [11]. In the first case, you reduce the risk of compromised legitimate packages. In the second, you stay up to date with the latest security updates. Regardless of which approach you choose there are benefits of running regular malware and vulnerability scans on your entire development pipeline.

GitHub Action Workflow Specific Controls Against Package Subversion

  • Pin Actions to Specific SHAs:
    • Always pin GitHub Actions to specific commit SHAs to avoid using compromised action updates.
  • Fork and Maintain Critical Actions Internally:
    • Internally fork and maintain important actions to strictly control the changes introduced to your workflows.
  • Secure Access Tokens and Credentials:
    • Regularly rotate Personal Access Tokens (PATs) and limit their scope strictly to required permissions.
    • Regularly audit and tightly manage repository secrets.
  • Use verified GitHub Actions
    • Verified GitHub actions help you identify the creators and the community supporting them.

Detecting compromised packages with Endor Labs

As part of our Software Composition Analysis (SCA) tool, Endor Labs helps you monitor for known malicious packages and detect suspicious code snippets and behaviors. Read Detect Malicious Packages Among Your Open Source Dependencies to learn more about how this works and book a demo to talk through your use cases

References

  1. https://www.library.hbs.edu/working-knowledge/open-source-software-the-nine-trillion-resource-companies-take-for-granted (Harvard Business School)
  2. https://github.com/tj-actions/changed-files/network/dependents (GitHub)
  3. https://www.endorlabs.com/learn/blast-radius-of-the-tj-actions-changed-files-supply-chain-attack (Endor Labs)
  4. https://www.endorlabs.com/learn/github-action-tj-actions-changed-files-supply-chain-attack-what-you-need-to-know (Endor Labs)
  5. https://github.com/tj-actions/changed-files/issues/2464 (GitHub)
  6. https://github.com/reviewdog/reviewdog/issues/2079 (GitHub)
  7. https://pulse.latio.tech?utm_source=navbar&utm_medium=web (Latio)
  8. https://www.wiz.io/blog/github-action-tj-actions-changed-files-supply-chain-attack-cve-2025-30066 (Wiz)
  9. https://www.wiz.io/blog/new-github-action-supply-chain-attack-reviewdog-action-setup (Wiz)
  10. https://unit42.paloaltonetworks.com/github-actions-supply-chain-attack (Palo Alto Networks)
  11. https://arxiv.org/pdf/2502.06662 (Carnegie Mellon University)

The Challenge

The Solution

The Impact

Book a demo

Book a demo

Book a demo

Welcome to the resistance
Oops! Something went wrong while submitting the form.

Book a demo

Book a demo

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Book a demo