How Open Source Dependency and Repo Attacks Compromise DevOps Pipelines and How to Stay Safe 

According to Sonatype, modern applications are composed of up to 90% open source components. This reliance has significantly accelerated development by allowing teams to reuse existing libraries and modules instead of building functionality from scratch. 

Code repositories serve as the primary mechanism for distributing and maintaining open source software, whether developed by independent communities or backed by a single organization. 

However, code repositories are a common entry point for cyberattacks and a channel for propagating vulnerable components. Black Duck reports that 93% of codebases include components with no development activity in the past two years, and 92% contain components that are more than four years out of date. Limited visibility and maintenance lead to increased exposure to risk. 

As a result, critical vulnerabilities are regularly discovered, with high-impact examples seen in projects such as Log4j and OpenSSL. There is also the risk of the repository itself being compromised. 

Source code repositories are high-value targets and are continuously scanned and monitored. Attackers look for vulnerabilities, exposed secrets and opportunities to introduce malicious code.  

Projects without secure development practices, such as code reviews and controlled commit access, are especially vulnerable. The more popular a project is, the more likely it is to already be under active scrutiny by attackers. A single successful compromise of a repository can impact hundreds or even thousands of systems, from individual developer machines to production environments. 

Two Core Risks in Open Source Supply Chains 

Two threat classes dominate this area, and security experts often disagree on which one is more critical.  

The first is inherited vulnerabilities, which arise from outdated or unmaintained dependencies that remain embedded in software long after fixes are available. When a CVE exists, has a documented exploit and the affected component is still shipping in production, the risk shifts from theoretical to highly probable, depending on exposure and reachability. In many cases, attackers do not need sophistication. Public exploits, scanners and automated tooling make these weaknesses easy to identify and weaponize at scale. 

The second threat is the introduction of malicious code through the repository supply chain — backdoors and undeclared functionality delivered via compromised packages, typosquatting or dependency confusion attacks. Ecosystems such as npm, PyPI and NuGet are frequent targets. 

Attackers publish packages that mimic legitimate libraries by name or exploit how package managers resolve dependencies across private and public registries. Once a malicious package is introduced into a build pipeline, it can access sensitive data, execute arbitrary code during installation or runtime or remain dormant until specific conditions are met, in some cases persisting undetected for extended periods. 

Practitioners often reduce both risks to the same root problem: Weak dependency governance. Known vulnerabilities are at least discoverable — scanners can identify most of them, patches often exist and CVE databases document their impact. 

Supply chain injections operate differently. Even modern SAST and SCA tools may not flag a well-crafted malicious package, especially when no known vulnerability is associated with it and its behavior aligns with expected usage patterns. The risk also propagates differently: A single compromised package can spread across a large number of downstream projects before detection. 

The counterargument is that unpatched vulnerabilities pose broader systemic risk due to their scale and persistence across environments. Supply chain attacks, while harder to detect and potentially more damaging per incident, are often more highly targeted, though some campaigns achieve wide distribution. 

Both vectors exploit the same root condition: Organizations consume open source components they do not fully control, verify or continuously assess. 

High-Profile Cases 

The number of cybersecurity incidents involving code repositories is quite large, and each one underscores the need for structured incident tracking and a reliable DevOps ticketing system to coordinate response. 

Let’s look at some illustrative examples: 

  • In November 2017, attackers breached Bitcoin Gold’s GitHub repository and replaced the official Windows wallet installer with a malicious version targeting cryptocurrency theft and credential harvesting. The file was live for 4.5 days, triggered no antivirus alerts and was only caught when the development team noticed the SHA-256 checksum no longer matched the original. 

 

  • In November 2020, Sonatype’s automated monitoring flagged discord.dll — a counterfeit npm package masquerading as a Discord plugin. It had been stealing Discord tokens and Chromium browser data for five months before detection, accumulating around 100 downloads with no antivirus flags. The payload ran via an obfuscated postinstall script, triggered automatically on package install and was traced to a compromised npm author account linked to an earlier stealer campaign.  

 

  • In February 2021, researcher Alex Birsan breached internal build pipelines of 35 companies, including Microsoft, Apple and Uber, by publishing public packages with the same names as their private internal dependencies but with higher version numbers, causing package managers to pull his code automatically. Birsan acted ethically. Within a week, attackers copied the technique, and Sonatype recorded a 7,000% spike in malicious copycat packages on npm, several of which stole Linux password files and opened remote shells. 

 

  • In March 2021, attackers compromised git.php.net and pushed two commits to PHP’s official repository, impersonating its creator and a core maintainer. Disguised as typo fixes, the code injected a zend_eval_string backdoor triggered by a crafted HTTP User-Agent header, enabling RCE on any server running the compromised build. With PHP powering roughly 80% of websites, the potential impact was enormous. The backdoor was caught during post-commit review within hours.  

 

  • In January 2022, Marak Squires deliberately sabotaged his own npm libraries colors.js and faker.js — downloaded 25 million and 2.8 million times per week, with nearly 19,000 and 2,500 dependent projects, respectively. He introduced an infinite loop in colors and purged Faker’s codebase entirely, breaking thousands of applications, including Amazon’s CDK, protesting corporations profiting from open source without compensating maintainers. Both sabotaged versions were pushed simultaneously to GitHub and npm. 

 

  • In March 2022, Brandon Nozaki Miller (RIAEvangelist) injected his peacenotwar package as a dependency into node-ipc, downloaded over a million times weekly. Versions 10.1.1 and 10.1.2 checked the host’s IP geolocation and overwrote every accessible file with a heart emoji if the machine was located in Russia or Belarus. Snyk rated the vulnerability CVE-2022-23812 as critical, scoring 9.8 out of 10. 

 

  • In January 2024, a malicious npm package named oscompatible deployed a Windows-targeted remote access trojan that downloaded tools such as AnyDesk. The attack used DLL sideloading and staged payload delivery to establish command-and-control access and monitor user activity. The package was published on January 9 and downloaded about 380 times before it was removed.  

 

  • In July 2025, attackers used GitHub to distribute Lumma Stealer disguised as free VPN tools and Minecraft utilities. The campaign relied on staged loaders, DLL sideloading and process injection into legitimate Windows binaries. Payloads were delivered via password-protected archives and obfuscated code, enabling covert data theft and command-and-control communication. 

19 Practical Controls for Open Source Supply Chain Risk  

First, close the package intake path. 

1. Break ‘Implicit Trust’ in Package Managers 

The Birsan attack used no malware, only a public package resolving ahead of a private one. Never let package managers choose between sources. Enforce internal mirrors, explicit source mapping and namespace scoping bound to internal registries. 

2. Enforce Dependency Provenance, not Just Version Checks 

Typosquatting and maintainer account takeover look identical to legitimate packages at the version level. Checking origin URL, maintainer count, package age and reputation catches what version scanners are blind to. 

3. Pin Dependencies With Integrity, not Ranges 

Version ranges can silently pull in a newly published bad release. During the colors.js and faker.js sabotage, projects that resolved to the affected versions could automatically ingest the destructive update. Pinning exact versions and enforcing hash verification is the first line of defense against silent poisoning. 

4. Use Package Reputation and Life Cycle Signals as Policy Inputs 

A package published three days ago with one maintainer and 12 downloads should not pass the same intake gate as a mature, widely used library. Age, activity and download patterns are strong signals of risk before any CVE exists. Modern AI security tools increasingly evaluate these signals automatically, using behavioral and metadata-based scoring. 

5. Treat Postinstall and Build Scripts as Untrusted Code 

The discord.dll attack was executed through an npm postinstall hook, and many open source attacks abuse install-time script execution to run arbitrary code the moment a package is installed. Any package install flow that permits life cycle or setup scripts should be treated as a potential execution event. 

6. Enforce Hash Verification as a Hard Gate 

Bitcoin Gold’s attack was only caught because a developer manually checked the SHA-256 checksum. Without hash verification enforced automatically in CI, a tampered file at the registry level passes through completely undetected. 

7. Integrate Dependency Validation Into Developer Workflow 

Catching a bad dependency at the IDE or pre-commit stage minimizes remediation cost and prevents propagation. Issues detected after the merge require reverts, pipeline reruns and may already have reached staging or downstream builds.22 

8. Turn Dependency Audit Into a Strict Allow/Deny Model 

Advisory-mode scanning produces reports that get triaged into backlogs and are often ignored. Enforcement mode makes unsuppressed findings block builds, forcing remediation before deployment and turning scanning into actual risk reduction rather than post hoc visibility. 

Next, reduce the hidden dependency risk.

9. Treat Dependency Abandonment as a Trigger for Replacement 

Unmaintained packages are unlikely to receive timely security fixes. When a vulnerability is disclosed, remediation shifts to you: Replace the dependency, fork and patch it or apply compensating controls. In practice, exploit development for abandoned projects often outpaces typical enterprise response cycles. 

10. Reduce Dependency Surface Aggressively 

Modern npm packages often pull in dozens of transitive dependencies, each extending the attack surface beyond what developers explicitly chose. Reducing dependency count directly lowers exposure and simplifies verification, rather than relying solely on detection after compromise. 

11. Prioritize High-Impact Dependencies 

Not all dependencies carry equal risk. Core libraries used across services require stricter controls than low-impact or dev-only packages. Identify the 10–20 dependencies whose compromise would propagate widely and enforce stricter pinning, faster patch SLAs and continuous monitoring. During Log4Shell, many teams were unaware that they depended on Apache Log4j transitively. 

12. Formalize Dependency Tree Visibility as an Operational Requirement 

Most exploited vulnerabilities originate in second- or third-level transitive dependencies that teams never consciously added. Without full dependency graph visibility, exposure remains hidden, and detection, prioritization and response controls operate with incomplete context. 

Strengthen detection and runtime visibility. 

13. Treat a Maintainer Account Change as a Security Signal 

New dependencies, version jumps and altered resolution paths often signal an attack before any CVE exists. Maintainer changes are one of the highest-priority signals: Ownership transfers or unfamiliar account activity must trigger immediate re-evaluation.  

14. Monitor Upstream Advisories, not Just CVEs 

Do not rely solely on CVEs. Ecosystem advisories and project disclosures often appear first. During Log4Shell, exploitation and fixes began before full NVD enrichment. Teams tracking Apache and GitHub patched faster, while CVE-only workflows lagged active attacks. 

15. Isolate Build Environments Aggressively 

When a malicious postinstall script executes, ephemeral runners without persistent credentials and with tightly restricted network egress significantly limit data access and exfiltration paths. This does not eliminate risk, but it reduces the blast radius and constrains the attacker’s actions before detection and response mechanisms engage. 

16. Monitor Behavioral Anomalies, not Signatures 

Signature-based controls often miss supply chain attacks. Malicious packages can evade CVEs and SAST, as seen in incidents like the ua-parser-js compromise. Unexpected outbound connections or DNS activity during build or install are high-signal indicators that persist even when code appears legitimate. 

17. Create a Fast Removal Path for Compromised Packages 

Malicious updates can propagate rapidly across downstream builds, as seen in the node-ipc protestware incident. The longer a compromised version remains available, the wider its impact is. Rapid block and rollback across build pipelines is critical to containment and should be coordinated as a formal incident response procedure within your ITSM process, not handled ad hoc. 

18. Use SBOM as a Runtime Control, not Just Inventory 

When Log4Shell dropped, teams without a live SBOM spent days asking, “Do we even use this?” A queryable SBOM tied to deployed artifacts enables rapid exposure assessment, significantly reducing response time compared to manual dependency tracing. 

19. Continuously Scan Deployed Workloads 

Build-time scanning is a snapshot. Vulnerabilities disclosed after deployment will not be detected without ongoing re-scanning of images or running workloads. Log4Shell hits deployed systems, not build pipelines. 

Final Thoughts 

The core issue is not awareness; it is control at the point where dependencies enter the system.  

Many teams invest in scanners, SBOMs and post-deployment visibility, while leaving the intake path largely uncontrolled. Dependencies are still resolved implicitly, install scripts execute without scrutiny and version changes pass through pipelines without focused review. 

This creates a structural gap. Security appears mature, but the point of highest leverage remains exposed. Controls are applied after risk is already introduced, not where it originates. 

Read More

Scroll to Top