SCA

ENISA's advisory on the secure use of package managers: an overview

The risks of third-party packages and ENISA's four-stage approach to selecting, integrating, monitoring and fixing dependencies, with practical checks.

Every npm install, pip install or Maven build pulls code written by people you’ve never met into your product. In March 2026, ENISA published the Technical Advisory for Secure Use of Package Managers, a short, practical guide to doing that safely. This article summarizes it and adds a few notes from our own SCA work.

What the advisory covers

The advisory is version 1.1. It was revised after a call for feedback between December 2025 and January 2026 that drew 15 contributions, and it’s licensed under CC BY 4.0.

Its scope is deliberately narrow: consuming packages and managing dependencies at the application level. Operating system package managers, publishing packages securely, the security of the registries themselves and secure coding are out of scope. The examples mostly use npm and GitHub, but the principles apply to any ecosystem.

You install more than you think

The advisory opens with a simple example. A ten-line Node.js web server using the express framework pulls in around 27 direct dependencies, and 68 packages in total once the transitive dependencies are resolved. Each of them is now part of your product.

ENISA makes two points about this that are worth repeating:

  • “Third-party” code stops being someone else’s once it’s in your build. It becomes part of your trusted codebase and deserves the same scrutiny as your own code.
  • Installed code isn’t the same as reachable code. Your application may only ever execute a small part of a package. A vulnerability in code that’s never executed is less likely to be exploitable, but “not directly reachable” isn’t a guarantee: reflection, misconfiguration or crafted input can open unexpected paths.

The same interconnectedness that makes package managers useful also spreads problems. Nearly 100,000 packages depend directly on express, and well over a million projects rely on it once you count transitive use.

Two kinds of risk

ENISA groups the risks of package consumption into two categories.

Packages with inherent vulnerabilities

The first category is weaknesses in the packages themselves: insecure code or design, overly permissive defaults or exposed debug modes. These end up in your attack surface even though you didn’t write them.

Unmaintained packages make this worse. The advisory’s examples:

  • node-serialize: its latest version, released 11 years ago, has a known critical deserialization vulnerability. The only remediation is not to use it, yet it still gets weekly downloads.
  • tokio-tar: the “TARmageddon” vulnerability came from this abandoned Rust library, years after it stopped being maintained.
  • crypto-js: discontinued according to its repository, but still downloaded millions of times a week.

Supply chain attacks

The second category is attacks where someone compromises a supplier to reach its customers:

AttackHow it worksExamples from the advisory
Malicious packagesAn attacker publishes a new package with malicious code and waits for developers to install it, directly or as a transitive dependency.crypto-encrypt-ts; GlassWorm malware in VS Code extensions
Compromised legitimate packagesAn attacker gains publishing rights through a stolen or socially engineered maintainer account, or a maintainer turns the package against its users.event-stream, ua-parser-js, the September 2025 npm attack on 18 packages with 2.6 billion weekly downloads, colors and faker
TyposquattingA malicious package with a name close to a popular one, waiting for a typo.crossenv imitating cross-env
Dependency confusionA public package with the same name as an internal one and a higher version number, picked up by build tools that consult both registries.The 2021 research that reached dozens of large companies

Either way, the effect cascades. The advisory points to CVE-2025-55182 in React, rated CVSS 10.0, which early estimates linked to over 12 million websites.

Four stages of package consumption

The core of the advisory is a simple life cycle for every dependency: select, integrate, monitor and mitigate. The first two stages build security in; the last two keep it there. For each stage, ENISA gives recommendations and a cheat sheet with example commands.

1. Select: choose trustworthy packages

Before evaluating a package, ask whether you need it at all. Fewer dependencies mean a smaller attack surface and less to manage. Then check:

  • that it comes from an official registry, ideally published through a secure workflow with provenance, such as npm’s Trusted Publishing
  • its known vulnerabilities, in OSV, the EU Vulnerability Database (EUVD), the NVD or a commercial database
  • that the package and registry support signatures and integrity hashes, and that you’re not installing straight from a Git repository or tarball URL that bypasses those checks
  • the maintainers: be careful with packages from new, single-project accounts
  • signs of active maintenance: recent commits, tagged releases, handled issues, a SECURITY.md file. ENISA warns that stars and download counts can be inflated and shouldn’t be used on their own.
  • install scripts that download extra code or binaries from external URLs

For example, with npm:

npm audit signatures          # check signatures and provenance
npm view <package> scripts    # look for pre- and post-install scripts
npm view <package> maintainers
npm ls --all                  # review the full dependency tree

ENISA also suggests maintaining an internal allowlist of approved packages or maintainers where feasible.

2. Integrate: keep what you install under control

  • Generate an SBOM during every build, so you have a record of every dependency for security and compliance.
  • Fail the build when it contains components with known high or critical vulnerabilities.
  • Enforce integrity: npm checks the SHA-512 hashes in the lockfile automatically; pip needs --require-hashes.
  • Restrict installs to trusted registries, ideally through a local registry or proxy such as Nexus Repository, JFrog Artifactory or Verdaccio. A caching proxy also keeps your builds working if a package disappears upstream.
  • Disable install scripts where you can, accepting that some packages may break.
  • Pin versions with a committed lockfile and use it in CI (npm ci). Review changelogs before upgrading.
npm ci --ignore-scripts                      # install exactly the lockfile, no install scripts
npm audit --omit=dev --audit-level=high      # fail on high or critical findings
pip install --require-hashes -r requirements.txt

ENISA flags the trade-off with pinning: it protects you from unreviewed updates, but prolongs your exposure to known vulnerabilities if nobody reviews and applies updates regularly. The advisory also mentions an optional, situational measure: install only versions published at least a few days ago. That gives the community time to spot a malicious release before it reaches your build.

3. Monitor: notice when something changes

Dependencies that were safe on the day you added them don’t stay that way. ENISA recommends:

  • using SBOM data for continuous vulnerability checks, for example with Grype or OSV-Scanner
  • scanning dependencies in CI on a schedule, not only when the code changes
  • following vulnerability feeds such as EUVD, OSV and the NVD, and machine-readable vendor advisories in CSAF
  • watching for outdated versions
  • alerts for new CVEs in locked versions, deprecated or unmaintained releases, lack of maintainer activity and maintainer or ownership changes

That last group is easy to overlook. A change of maintainer was the starting point of the event-stream attack, and few teams watch for ownership changes.

4. Mitigate: assess before you fix

The advisory is refreshingly honest about SCA findings. A vulnerable version in your dependency tree means the package contains code that could be exploited under specific conditions. It doesn’t automatically mean your application is vulnerable.

ENISA’s mitigation steps:

  1. Assess the finding with more than the CVSS score: EPSS for the probability of exploitation, CISA’s Known Exploited Vulnerabilities catalog, VEX statements from the supplier, and reachability analysis with tools such as CodeQL or Semgrep.
  2. Prioritize against a defined risk threshold, for example “CVSS 7.0 or higher, or EPSS 0.3 or higher, is high priority”, and focus on reachable, exploitable vulnerabilities in production dependencies.
  3. Mitigate by upgrading, applying a temporary control such as a WAF rule or feature flag, or removing, rolling back or isolating the package if no fix exists.
  4. Document and notify: record a VEX status (affected, not affected, under investigation or fixed), regenerate the SBOM, update the release notes and inform customers, authorities or internal teams where needed.

Automation and AI-assisted development

The advisory closes with two forward-looking notes. Manual checks don’t scale to hundreds of dependencies across many repositories, so SBOM generation (Syft, CycloneDX), scanning (Grype, OSV-Scanner) and install controls belong in the CI/CD pipeline.

And AI coding assistants change who chooses dependencies. When code is generated with little human review, nobody may know why a package was added. ENISA mentions “slopsquatting”: attackers registering package names that AI tools hallucinate. Its advice is to keep visibility over every package that AI-generated code introduces, review whether each one is needed, automate the selection and integration checks, and strengthen detection and response to make up for the reduced scrutiny up front.

Why this matters for the CRA

The Cyber Resilience Act makes much of this mandatory for manufacturers. They must exercise due diligence when integrating third-party components, open source included, draw up an SBOM, and identify and remediate vulnerabilities in the components they ship throughout the support period. The advisory doesn’t mention the CRA by name, but its four stages read like a practical implementation of those obligations. Our CRA guide for SMBs covers them in detail.

Our take

For teams working in npm, Python or Java, this is a good checklist to put next to the CI pipeline. It’s short, it’s concrete, and the cheat sheets turn each recommendation into a command you can try today. The mitigation section deserves particular attention: teams that treat every SCA finding as equally urgent burn out on false positives and miss the few that matter.

Two caveats. The examples are heavily npm-focused; the advisory says the principles apply elsewhere, and they do, but you’ll need to find the equivalent controls in your own ecosystem. And C and C++ aren’t covered at all, even though they bring their own problem: SBOM components often lack the identifiers vulnerability databases need. Our article on CPE enrichment for C++ libraries in Conan builds covers that gap, and our guide to deploying OWASP Dependency-Track shows one way to implement SBOM-driven monitoring. For SBOMs in general, see our overview of ENISA’s Technical Advisory for Software Bill of Materials.

ENISA also stresses that the tools it names are examples, not recommendations. The point is the control, not the brand.