Three Supply-Chain Campaigns in 48 Hours: pgserve Was Wormable, xinference Was Stealth, and the npm-PyPI-Docker Triple Hit Nobody Talks About
- Patrick Duggan
- 28 minutes ago
- 4 min read
April 21 through April 23, 2026. Forty-eight hours. Three independent supply-chain compromises hitting npm, PyPI, and Docker Hub. All three targeting secrets — API keys, cloud credentials, SSH keys, CI/CD tokens. GitGuardian framed it as "no off-season." They were right and the framing is worth our spin because the three campaigns each picked a different physics of attack.
The wormable one is the one nobody is talking about loud enough.
CanisterSprawl. April 21. A malicious version of pgserve — a PostgreSQL server for Node.js — published to npm. The novel piece is the postinstall hook. Every time someone runs npm install pgserve, the hook fires, searches the host for npm publish tokens, and then for every package the victim is authorized to publish, the worm bumps the patch version, injects itself, and ships the new poisoned release. One developer with broad publish rights infects every package they own in a single npm install.
That is wormable npm again. Not Shai-Hulud Original from 2025 — a new operator, fresh malware, but the same self-propagating publish-token logic. Anyone in the security space who lived through Shai-Hulud V2 in December 2025 should be feeling deja vu. The lesson from V2 was straightforward: revoke every npm publish token that could have been on a dev box during the window, and audit your published-as-me list for any version bumps you did not author. The lesson applies again. Whatever you published in the last twelve days, diff it against your last known-good release.
xinference on PyPI. April 22. Three consecutive releases of the model-serving framework, each carrying a credential-harvester. SSH keys, cloud credentials, environment variables, crypto wallets. Stealthy, no self-propagation, just smash-and-grab. Indexed in our iocs as Xinference-Harvester.
The Docker Hub component of GitGuardian's reporting is fuzzier — they describe a parallel campaign hitting container images during the same window, also focused on secrets. We are still building our ingest pipeline for malicious container images and do not have first-party receipts on that one yet, so we will not overclaim. The point of the cluster is not the Docker piece in isolation. It is that npm, PyPI, and Docker all got hit independently inside a forty-eight hour window, by what appear to be three different operators, all chasing the same prize. Tokens. Cloud creds. Build secrets.
This is not a coincidence. This is the market.
Crypto-stealers used to be the supply-chain payload of choice — drop a wallet-grabber, drain whatever Phantom-extension wallets you find. The economics drifted. Tokens beat wallets. A single npm publish token with broad permissions resells for more than a thousand drained Phantom wallets and the buyer can monetize for months. A GitHub Actions secret that touches a CI/CD pipeline with prod access is worth a year of crypto-stealer haul. So the payload pivots. Lightning, xinference, intercom-client, pgserve. Different namespaces, different ecosystems, same loot.
What we did about it today.
Indexed all four campaigns into our iocs index — Lightning-PyPI-Stealer, Xinference-Harvester, CanisterSprawl, plus the intercom-client cluster cross-link. Customers pulling our STIX feed get them on the next pull. Search the analytics search API for any of the four malware-family tags and you will see the campaign records, the affected versions, the actor metadata, and the references straight back to the Socket and GitGuardian disclosures.
We did this in twenty minutes. Patrick was at the May Day protest in Minneapolis, so it ran on autopilot — same workflow we run any other day, just without a deploy gate because there is no infrastructure change in indexing IOCs. Threat-intel ingest is content. Content runs autonomous.
What you should do about it.
Audit your npm publish tokens. Every one of them. If a token was on a developer machine during the April 21 to 23 window, rotate. Visible-in-source equals leaked, and visible-on-a-poisoned-postinstall-hook is a strict superset of that.
Pin your ML stack. Lightning 2.6.1 was the last clean Lightning release. xinference: roll to the version published before April 22. intercom-client: same drill. Diff against the wheels in your CI cache.
Stop treating dev environments as third-class. The CanisterSprawl postinstall pattern only works because dev machines routinely have publish-grade credentials sitting on disk. That has to stop. Tokens belong in a credential broker, scoped per-job, with audit log. If your security architecture says "we trust the developer's laptop," you are paying for the next CanisterSprawl out-of-pocket whether you know it or not.
The 95 percent cap.
Three campaigns in forty-eight hours is statistically a bad week, not a permanent regime change. We are calling the trend at high confidence — the secrets-economy pivot is real, and the maintainer-namespace attack pattern is not slowing down. We are not calling it 100 percent because Murphy was an optimist and the next campaign is going to be one nobody saw coming. Cap at ninety-five. Make the rotations anyway.
Receipts at the search API. Defense at the rotate button.
How do AI models see YOUR brand?
AIPM has audited 250+ domains. 15 seconds. Free while still in beta.
