Get early access

Stop the next npm supply chain attack at the registry

MopokeHQ runs a registry proxy for npm, Composer and Docker, hosted and isolated per organisation. Your builds pull through it. New versions wait out a cooldown, known-malicious packages never arrive, and every download is logged.

The supply chain proxy is a paid add-on to MopokeHQ.

Recent attacks needed one publish, not a vulnerability

Most of these versions were live for hours, not weeks. The builds that got hit were the ones that installed inside that window. A registry you control can keep you out of it.

DateWhatHowSource
8 Sep 2025chalk, debug and 16 other packagesnpmA maintainer was phished with a fake 2FA reset. The malicious versions hijacked crypto wallet transactions in browsers.StepSecurity
Sep 2025Shai-Hulud wormnpmStole GitHub and cloud credentials, then published infected versions of the victim’s other packages. CISA advised pinning and rotating credentials.CISA
31 Mar 2026axios 1.14.1 and 0.30.4npmA maintainer account takeover added a new dependency whose postinstall script dropped a remote access trojan. The versions were live for about three hours.CSA Singapore
11 May 202642 @tanstack packagesnpmA poisoned CI cache let attackers publish 84 malicious versions through the project’s own release pipeline. They carried valid provenance.TanStack
22 May 2026Laravel-Lang packagesComposerAttackers rewrote existing Git tags so old version numbers pointed at a credential stealer loaded through Composer autoload.BleepingComputer

The axios versions were removed about three hours after they were published. A 24 hour cooldown would have kept both out of every install that resolved through it.

What the proxy does

Each organisation sets its own policy. It applies to every laptop, runner and Dockerfile that pulls through the proxy.

The same package checks on merge requests
Release cooldown
Versions younger than your cooldown, for example 24 hours, are hidden from installs
Known malicious
Always blocked. No setting turns this off
Quarantine
Suspicious versions are held until a person reviews them
Typosquats
Names one slip from a popular package are flagged
New packages
Packages that appeared days ago are flagged
Download logs
Every download through the proxy is recorded

Private packages stay in your GitLab

Your private packages stay in your own GitLab package registry. Private scopes never resolve to a public registry, so nobody can publish a public package with your internal name and have your build pick it up.

That attack is called dependency confusion, and it matters on GitLab in particular: by default, GitLab’s npm registry redirects requests for packages it cannot find to npmjs.com.

Public packages
Through the MopokeHQ proxy, with your policy
Private scopes
Your GitLab package registry only
Public lookup
Never, for a private scope

Point npm, Composer and Docker at it

One file per ecosystem. Commit it with the project, or set it once on your runners. The exact hosts and your token appear in MopokeHQ when you switch the proxy on; the ones below are placeholders.

.npmrc
# Public packages through the MopokeHQ proxyregistry=https://npm.your-org.mopokehq.example///npm.your-org.mopokehq.example/:_authToken=${NPM_TOKEN}# Your private scope stays on your GitLab package registry@your-scope:registry=https://gitlab.example.com/api/v4/groups/123/-/packages/npm/
composer.json
{  "repositories": [    { "type": "composer", "url": "https://gitlab.example.com/api/v4/group/123/-/packages/composer/packages.json" },    { "type": "composer", "url": "https://composer.your-org.mopokehq.example" },    { "packagist.org": false }  ]}
Dockerfile
FROM docker.your-org.mopokehq.example/library/node:22

One policy for every client

npm, pnpm, Yarn, Bun and Composer each have their own cooldown setting, with their own names and units. Older npm versions ignore the setting without warning. Docker has no setting at all.

Set the client settings anyway; they cost nothing. The proxy adds one policy, set once, that holds whatever client version a laptop or runner happens to have.

ClientSettingCounts in
npm 11.10+min-release-ageDays
pnpm 10.16+minimumReleaseAgeMinutes
Buninstall.minimumReleaseAgeSeconds
Composer 2.11 RCpolicy.cooldownA duration
DockerNonen/a

Part of MopokeHQ

The proxy decides what can be installed. The rest of MopokeHQ keeps watching what already was.

How MopokeHQ works
  • Continuous matchingEvery stored SBOM is re-checked when an advisory lands. A package you already installed that is later flagged as malicious becomes a P1 with an instant email.
  • Merge request gatePipelines fail on a new known-exploited dependency by default. Existing debt goes on the roadmap.
  • Hosted and highly availableRuns in Sydney, with a documented break-glass switch if it ever stands between you and a production fix.

Questions

How do you avoid npm supply chain attacks?

Commit a lockfile and install with npm ci in CI. Set a minimum release age so brand-new versions wait before they install. Use phishing-resistant MFA on npm and GitHub accounts, and rotate tokens after any incident. A registry proxy adds one more layer: it applies a cooldown and blocks known-malicious packages for every machine that pulls through it.

Is npm still safe to use?

Yes, with care. Malicious versions are usually removed once reported, often within hours. The risk is installing during those hours. A cooldown, a lockfile and a check on brand-new packages cover most of that window.

What is a minimum release age, or dependency cooldown?

A setting that skips package versions younger than a set age. npm calls it min-release-age and counts days (npm 11.10.0 and later). pnpm calls it minimumReleaseAge and counts minutes, with 24 hours as the default from pnpm 11. Composer added a cooldown policy in its 2.11 release candidate. MopokeHQ applies the same idea at the registry, so it covers every client version.

What is dependency confusion?

An attacker publishes a public package with the same name as one of your private packages. If your package manager checks the public registry, it may install theirs. With MopokeHQ, private scopes never resolve publicly, and your private packages stay in your GitLab package registry.

Does it work with Composer and Docker as well as npm?

Yes. The proxy covers npm, Composer (Packagist) and Docker/OCI images, with one policy per organisation.

What happens if the proxy is down?

It runs highly available in Sydney. If you ever need to bypass it, there is a documented break-glass switch.

Does the proxy replace npm audit or composer audit?

No. Audits look for known vulnerabilities in what you already installed. The proxy decides what can be installed in the first place. MopokeHQ’s continuous matching covers the audit side.

Put the registry on night watch

The supply chain proxy is a paid add-on, priced separately from your MopokeHQ plan.