A new software supply chain attack pattern emerged and spread in the past year. Across these attacks, bad actors are compromising trusted identities and using those identities to distribute open-source packages containing malicious code that executes during installation. This attack pattern has appeared repeatedly, including in Shai-Hulud (and all its variants), Axios, and LiteLLM.
Current Tooling Isn’t Designed for This Attack Pattern
Most conventional security tooling isn’t designed to detect malicious packages at the time they enter build environments. Static application software testing (SAST) typically scans first-party code for vulnerabilities and is critical for identifying injection points, memory issues, hardcoded passwords, API tokens, or keys. It acts as a gate that blocks this data from being committed. SAST tooling usually runs on the developer workstation or in the IDE, scanning first-party code after it’s entered a build environment, but before it’s committed or shipped.
Software composition analysis (SCA) scans open-source dependencies for vulnerabilities, so on the surface it seems like SCA should be able to catch the install-time attack pattern. SCA tooling checks for malware, known CVEs, outdated packages with available patches, typosquatted packages, and licensing risks. Just as important as what SCA detects is where it runs. Like SAST, SCA can run on developers’ local workstations and in their IDEs, and it can also run during the CI build process as a gate for packages.
Conventional SAST tools evaluate source code, and SCA tools evaluate static package elements, like manifests and lockfiles. Neither evaluates the dynamic processes that run at installation, such as lifecycle hooks like postinstall scripts. Tools that run on developer workstations or IDEs fire too early to stop install-time attacks, and those that run during the CI process are evaluating packages that are already in the build environment. The lifecycle scripts that run as part of an npm package install, for example, run at the very start of the build process, when dependencies are installed and resolved, and before any first-party code is compiled or tested. This is precisely the gap that this new attack pattern targets.
Confidence in Security Tooling Doesn’t Match Adoption of Preventative Approaches
Despite the damage caused by Shai-Hulud and similar attacks, organizations remain confident in their open source security controls. A recent survey asked platform and security engineers about their preparedness for dependency attacks. Most respondents – 74% – were confident in their organization’s ability to prevent or minimize the impact of future open-source dependency attacks. When asked specifically about install-time attacks, 73% were confident that their current tooling would be able to stop that type of attack – even if there was no public threat advisory.
Stopping threats at the gate is the goal. But inevitably, some organizations will be impacted by these attacks. Teams also need to be able to identify threatening packages already in their environments so that they can reduce the blast radius and accelerate remediation. Confidence was even higher here: 78% said they could identify a malicious or vulnerable package within a day of a newly published threat advisory.
Confidence in the ability to prevent open-source dependency attacks, including install-time threats, is high, but that confidence hasn’t translated into adoption of the practices that would close the gap. The same survey found that 54% of organizations rely on a reactive response to dependency attacks, and another 8% didn’t have a consistent response at all. For install-time attacks, any solution that scans a package after it’s already in the system is reactive.
Organizations need to adopt proactive controls to mitigate and prevent this new class of open-source dependency attack. The most dangerous period for a malicious package is the zero-day window between when it’s published and when a threat advisory comes out. This is the period when teams are most exposed, because automated pipelines pulling the latest tagged version have no way to distinguish a compromised release from a legitimate one. To prevent this, implementing a cooldown policy holding packages for 3–7 days delays a compromised release long enough for a threat advisory to catch it. Only 24% of organizations automatically enforce cooldown periods for newly released packages.
Once a threat advisory exists, teams can incorporate that threat intelligence into security policy. Enforcing policy at the point of ingestion allows teams to block or quarantine packages before reaching developer environments. Only 38% of respondents scan for vulnerable and malicious packages before ingesting them.
Teams that pulled a malicious package during the zero-day period need a proactive way to identify that package as soon as threat intelligence hits public threat data feeds. Waiting a day or a week for a scheduled scan increases the exposure window at a time when the goal is to compress it. In this situation, teams need the ability to ingest threat data and use that data to continuously evaluate every package in their repository in real-time. Only 38% of teams say they continuously evaluate packages in their system against new threat intelligence.
Enforcing Policy at the Artifact Registry Enables a Proactive Security Response
Package ingestion sits between public open-source registries and build pipelines, so it’s the last point where packages can be evaluated before they land in a development environment.
In practice, these three proactive controls are often implemented together, wherever teams enforce policy on incoming packages. Commonly, this occurs at the registry or artifact management layer that sits between public sources and the build pipeline. Teams can enforce cooldown periods and layer in custom policies, ideally written as policy-as-code for granularity and control, to block malware and packages with known CVEs before they enter the environment.
An artifact manager retains a persistent set of metadata for every package over its lifetime; this is what makes continuous evaluation possible and enables this process to check new threat advisories against packages already in the repository and not just new ones coming in. When continuous evaluation identifies a compromised package, it triggers the security policies teams already wrote. When these controls live in the same layer, they reinforce each other – a blocked package, a cooldown hold, and a continuous re-evaluation all draw on the same policy and metadata, rather than running as disconnected checks.
KubeCon + CloudNativeCon is taking place in Salt Lake City, Utah, from November 9 to 12. Register Now!
