npm Supply Chain Security and the Code You Didn't Write

php2shell patches (CVE-2026-109618 and CVE-2026-109619) for EOL PHP are out now. With sales replies slower than usual due to high demand, the fastest route to patched packages is to buy ELS for Runtimes online (opens in new tab). Read the patch FAQ

Go straight to an AI summary of this blog post instead

  • Summarize this post with Perplexity
  • Summarize this post with Gemini

Every npm install is an act of trust. Have you ever stared at your node_modules folder and wondered, what is actually in here? In modern software development, we live in a weird space where we are responsible for an invisible iceberg of code that we didn’t write. Much of it arrives as transitive dependencies, packages nobody on the team picked directly. When that code ships to production, that accountability turns into anxiety. SecureChain provides a defensive layer for managing some of that third-party pressure.

The Transitive Dependency Iceberg

Before you ever install a package that comes in as a direct dependency, you might check the GitHub stars, the profile of the maintainer, and the profiles of contributors. The library rarely travels solo. A transitive package comes along for the ride because a direct dep requires it. Think of it like “packages of your packages,” even “packages of packages of your packages.” They can be multiple layers deep and remain untouched.

This iceberg runs deep, pun fully intended. A “basic” web app can easily skyrocket past 1K packages sitting in your node_modules. The transitive dependencies hidden deep are where supply chain attacks like to sit. They dramatically expand the third-party code you inherit, and manual auditing rarely reaches that far down.

The problem is not that transitive dependencies are bad; modern development depends on them. The problem is that the code you inherit grows faster than the code you review.

When Malicious Looks Legit

The anxiety stems from those packages that seem to be legit, yet are malicious in nature. As developers, we use a lot of muscle memory to get the job done. And now with AI, the process of getting the job done doesn’t even require that. Coding assistants sometimes suggest package names that do not exist. That opens a newer path called slopsquatting: register the name a model keeps hallucinating and wait.

Below is a list of some of the most common ones.

Typosquatting

Typosquatting exploits rely on attackers registering packages with names almost indistinguishable from legitimate, popular libraries, betting that somebody will mistype, skim, or trust a suggestion. These packages often mimic the target’s functionality so nothing immediately looks broken. Common tactics include:

  • Character substitution: Swapping letters, as in lodash and lodahs, a real malicious package that went after cryptocurrency wallets. New npm names must be lowercase and URL-safe, so lookalikes lean on tricks that survive those rules, like a 1 in place of an l.
  • Namespace or scope imitation: Registering scoped packages whose names closely mimic official libraries, distinct from the registry-resolution attack described below.
  • Format variations: Employing hyphenation tricks (e.g., crossenv vs. cross-env) or altering pluralization.

Because these packages can execute arbitrary code during installation, they can steal API keys, environment variables, or AWS credentials before anyone opens the source for review.

Dependency Confusion

Dependency Confusion attacks target organizations that use a hybrid of public and private registries. An attacker can exploit this setup by publishing a malicious package with the same name as an internal one, typically assigning it a higher version number. If your build configuration is not strictly isolated, the system may resolve the package name to the attacker’s public version instead of your internal one, automatically executing the malicious code upon installation.

None of this is theoretical. Alex Birsan proved it in 2021, publishing packages named after internal libraries and watching them resolve inside systems at Apple, Microsoft, and dozens of other organizations.

For those unfamiliar, scoped packages (e.g., @my-org/cool-package) use an @ symbol to namespace dependencies. Whether your organization is vulnerable often depends on how you configure your registry, scope, proxies, and lockfiles. Systems never audited for these routing behaviors are most at risk. To secure your pipeline, ensure your package resolution is deterministic. Map private scopes to your internal registry in .npmrc explicitly, so your package manager does not unexpectedly resolve that scope through the public registry:

@my-org:registry=https://registry.internal.example.com/

Claiming matching scopes on npmjs.com also prevents attackers from publishing under an identity you already own. Keep in mind that scoping is primarily a naming convention, not a security control. If the same dependency name can resolve from two different places, somebody else gets to make that decision for you.

Lifecycle Scripts

Package.json lifecycle hooks such a preinstall, install,and postinstall execute automatically during dependency installation, well before anyone on the dev team has actually looked at what’s inside.

These payloads home in on the highest-value targets: banking infrastructure, build servers, and the like. They pull out critical secrets, including .env files, AWS tokens, and SSH keys: the exact things we’re always told never to push to version control.

Certain scripts first probe the environment, checking for sandboxes or closely watched systems, and hold off on firing until they land somewhere less protected.

Shai-Hulud showed the scale this reaches. The September 2025 wave used postinstall to harvest npm tokens and cloud credentials across hundreds of packages, then republished itself with what it stole. The November wave moved execution earlier, into preinstall, so the payload ran before installation finished. Later variants hid inside optional dependencies, running the payload and then failing in a way npm tolerates.

That said, the default behavior has finally shifted. pnpm stopped running dependency lifecycle scripts automatically in v10, where anything that needs to build must be listed in onlyBuiltDependencies. npm v12, released July 8, 2026, took the same position: dependency scripts do not run unless the root package’s allowScripts policy permits them, and npm approve-scripts --allow-scripts-pending lists everything waiting on a decision.

There is a catch. An unapproved script is skipped with a warning and the install still exits 0, which can leave a native dependency half-built and push the failure later into your build or runtime. Commit the allowScripts block and set strict-allow-scripts=true in CI so unreviewed scripts fail the build instead. If you’re on npm 11 or older, the flag below handles that for you:

npm install --ignore-scripts

Useful, yes. Complete, no. None of this addresses execution at import time, and a malicious package whose top-level code fires the moment your app calls require() slips right past install-script protections.

So much pressure is put on our shoulders when it comes to accountability for the code we are shipping. In TuxCare’s 2026 Open Source Landscape Report, among respondents whose organizations reported a cybersecurity incident, 61.4% said a patch had been AVAILABLE and was never applied. That number should be extremely low. Knowing risk exists is not the same as removing it.

Dependency depth makes that harder. A fix sitting upstream does nothing for the copy pinned four levels down in your tree.

Manual review still belongs in the process, but hand-auditing a graph that size is not realistic. Lack of visibility into what you’re shipping can, and will, come back to compromise your stack.

Curing Anxiety with SecureChain

Managing dependency risk has to be a part of the policy. Achieving that management at scale can overwhelm any team out there. SecureChain changes the consumption path. Instead of resolving straight from the public registry, your builds pull from a TuxCare-managed registry of packages that were rebuilt, signed, and patched on a published schedule.

Every registry is still a trust decision. What changes is that more of that trust becomes verifiable.

Source Hardening

Every package, including transitive dependencies, is rebuilt from source in hardened, isolated environments and screened for known malware and suspicious code, rather than redistributing whatever artifact upstream published.

Continuous Patching

SecureChain delivers fixes under SLA as CVEs emerge. For packages that reach upstream end-of-life, Endless Lifecycle Support (ELS) keeps backporting critical and high-severity fixes to the versions you already run.

Point your package manager at SecureChain, or the repository manager you already run, which works with Artifactory and Nexus. What comes back is provenance built to support verifiable SLSA Level 3 compliance, VEX documents that say which CVEs affect a package version, and machine-readable SBOMs across supported components, with coverage still expanding. None of it replaces good hygiene. You still want lockfiles, scoped registry rules, and least-privilege CI credentials.

The Takeaway

You can put some of the anxiety away when shipping code you didn’t write. Security is an ongoing task and policy. It is never a “set it and forget it” mindset or practice. Understanding transitive deps and acknowledging the issues that arise from them will help you ship healthy production code.

The goal is not to stop trusting open source. We all depend on it. The goal is to stop treating that trust as invisible.

Using tools like SecureChain can take away some of that heavy burden we all sit with. Stay ahead of the game, and secure YOUR supply chain.

Summary
npm Supply Chain Security and the Code You Didn't Write
Article Name
npm Supply Chain Security and the Code You Didn't Write
Description
Most of your app is code nobody on the team picked. How npm supply chain attacks land, and how to shut the door on them.
Author
Publisher Name
TuxCare
Publisher Logo

Join 4,500+ Linux & Open Source Professionals!

2x a month. No spam.

Table of Contents
Get the open-source security answers you need

Join 4,500+ Linux & Open Source Professionals!

2x a month. No spam.