Open Source · · 1 day

pgserve npm CanisterSprawl credential stealer

On April 21-22, 2026, malicious pgserve npm versions 1.1.11 through 1.1.14 added a postinstall loader that harvested developer and CI secrets, encrypted them with RSA-4096 and AES-256, and exfiltrated to an Internet Computer Protocol canister.

On the evening of April 21, 2026, four back-to-back versions of the npm package pgserve were published with a postinstall hook that quietly harvested developer secrets and shipped them to a canister running on the Internet Computer blockchain.

Pgserve is a small development dependency that embeds a PostgreSQL server inside Node.js projects, the kind of utility a developer adds without much thought. Researchers at StepSecurity, who tracked the incident under the name CanisterSprawl, documented versions 1.1.11 through 1.1.13, and Ossprey subsequently identified 1.1.14, bringing the publication window to roughly five hours. None had a corresponding tag on the upstream Git repository, and the previous release, 1.1.10 from April 17, was the last legitimate one. The diff against it was blunt: the malicious tarballs added scripts/check-env.js and scripts/public.pem, then wired package.json to invoke the script during postinstall. The command was suffixed with || true, so any error inside the malware would swallow itself rather than surface a failed install to the developer.

Once it ran, the script swept the host for environment variables, package-manager tokens, SSH keys, cloud credentials, Kubernetes and database material, cryptocurrency wallets, and browser password stores. It wrapped the collection in a hybrid RSA-4096 and AES-256-CBC scheme using the bundled public key, then sent it to the Internet Computer canister cjn37-uyaaa-aaaac-qgnva-cai, with a secondary webhook at telemetry.api-monitor.com available when an environment key was present. Routing exfiltration through an ICP canister is unusual: the hostnames look like ordinary cloud endpoints and the traffic is hard to distinguish from legitimate Web3 activity.

The loader also tried to spread. Given an npm publish token, it enumerated the packages the victim could publish, copied check-env.js and public.pem into each one, bumped the patch version, and republished. A PyPI token triggered a parallel attempt using .pth file injection, a Python startup trick that runs code whenever the interpreter loads, carrying the campaign across an ecosystem boundary.

Appendix · Affected releases

pgserve npm fixed 1.1.10
1.1.11 no sample yet
1.1.12 no sample yet
1.1.13 no sample yet
1.1.14 no sample yet
  • StepSecurity reported pgserve@1.1.10, published on April 17, 2026 with git tag v1.1.10, as the last legitimate release before the compromised versions.
  • StepSecurity reported pgserve@1.1.11 at 2026-04-21 22:14 UTC and pgserve@1.1.12 at 2026-04-21 22:26 UTC; pgserve@1.1.13 was also published on April 21, 2026.
  • Ossprey subsequently identified 1.1.14 at 2026-04-22 03:35 UTC and published the npm SHA-1 integrity values for all four complete tarballs. Hash order follows versions 1.1.11, 1.1.12, 1.1.13, and 1.1.14.
  • The four compromised versions had no corresponding upstream git tag.

References

  1. CanisterSprawl: pgserve Compromised on npmstepsecurity.io
  2. Disclosure issue for malicious pgserve npm releasesgithub.com
  3. New npm supply-chain attack self-spreads to steal auth tokens - BleepingComputerbleepingcomputer.com
  4. No Off Season: Three Supply Chain Campaigns Hit npm, PyPI, and Docker Hub in 48 Hours - GitGuardianblog.gitguardian.com
  5. pgserve: Self-Propagating npm Worm with Blockchain C2 - Osspreyossprey.com

Source record: oss/attacks/pgserve/meta.yaml