pgserve npm CanisterSprawl credential stealer
On April 21, 2026, malicious pgserve npm versions 1.1.11, 1.1.12, and 1.1.13 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.
Story
On the evening of April 21, 2026, three 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, said versions 1.1.11, 1.1.12, and 1.1.13 went out between 22:14 and 22:26 UTC with no corresponding tag on the upstream Git repository. The previous release, 1.1.10 from April 17, was the last legitimate one.
The diff against 1.1.10 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.
Affected Artifacts
- Observed
- 2026-04-21 to 2026-04-22
- Fixed
- 1.1.10
- Evidence
- distribution: npmjs.com/package/pgserve/v/1.1.11, distribution: npmjs.com/package/pgserve/v/1.1.12, distribution: npmjs.com/package/pgserve/v/1.1.13, file: scripts/check-env.js , +10 more
- 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.
- StepSecurity said the three compromised versions had no corresponding upstream git tag.
Incident Context
- Motive
- Credential Theft
- Attribution
- Group
- Cause
- Compromised Account Credentials
- Transitive
- Yes
- Actor
- TeamPCP
External References
- CanisterSprawl: pgserve Compromised on npmstepsecurity.io
- Disclosure issue for malicious pgserve npm releasesgithub.com
Source record: oss/attacks/pgserve/meta.yaml