`@vpms/design-system` — internal-scope dependency-confusion with preinstall env-var exfil to Pipedream
On 2026-06-25 between 15:52 UTC and 17:14 UTC, an operator published four versions of @vpms/design-system (0.1.3, 1.0.0, 1.0.1, 1.1.2) as a dependency-confusion attack against the internal @vpms scope. The preinstall script iterates process.env and harvests every variable whose name contains SECRET, TOKEN, PASSWORD, KEY, or CREDENTIAL, along with hostname, username, and process details, then exfiltrates the payload to a hardcoded Pipedream webhook at eov0bmnid410yqf.m.pipedream.net. npm-support replaced all four versions with a 0.0.1-security holder on 2026-06-29.
- Detected by
- Amazon Inspector · OpenSSF Package Analysis · GitHub Security Advisory
- Also known as
- vpms design-system pentest
- Ecosystems
- npm
- Packages tracked
- 1
What happened
On 2026-06-25 between 15:52:53 UTC and 17:14:47 UTC, an operator published four versions of @vpms/design-system to the public npm registry — 1.0.0, 1.0.1, 1.1.2, and 0.1.3 (the out-of-order final publish backfills a lower version to catch consumers using ^0.1 ranges). The package title and README masquerade it as a "pentest design system" but the shipped tarball contains no design-system code; the entire payload is the preinstall lifecycle hook.
Preinstall env-var exfiltration
The package.json declares a preinstall script that runs before any user code on every npm install. The script iterates process.env, filters variables whose names contain any of the substrings SECRET, TOKEN, PASSWORD, KEY, or CREDENTIAL (case-insensitive), and collects them alongside host identifiers (os.hostname(), os.userInfo(), and the full process argv). The payload is JSON-stringified and POSTed via HTTPS to a hardcoded Pipedream webhook at https://eov0bmnid410yqf.m.pipedream.net.
The substring filter catches a wide spectrum of CI / developer environment variables — GITHUB_TOKEN, NPM_TOKEN, AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY, GCP_SERVICE_ACCOUNT_KEY, STRIPE_SECRET_KEY, SLACK_BOT_TOKEN, DATABASE_PASSWORD, generic *_API_KEY patterns, and so on. Anyone whose npm install runs with these populated (CI runners almost always have several; developer machines often have a few via direnv or .envrc) leaks them to the operator in a single round-trip.
Dependency-confusion targeting
The @vpms scope is unregistered in the public npm registry, so any internal @vpms/design-system package living on a private registry that is consulted alongside registry.npmjs.org is a dependency-confusion target. The operator's use of 1.0.0 → 1.0.1 → 1.1.2 version bumps targets the common SemVer range ^1.0.0 that internal consumers would write in their package.json. The trailing 0.1.3 publish backfills the rare consumer pinning a ^0.1 range. Detection sources include Amazon Inspector, OpenSSF Package Analysis, and GitHub Security Advisory, ingested by OSSF malicious-packages as MAL-2026-6467.
Disclosure timeline
- 2026-06-25 15:52:53 UTC —
@vpms/design-system@1.0.0published. - 2026-06-25 16:07:57 UTC —
@vpms/design-system@1.0.1. - 2026-06-25 16:23:58 UTC —
@vpms/design-system@1.1.2. - 2026-06-25 17:14:47 UTC —
@vpms/design-system@0.1.3(the out-of-order backfill). - 2026-06-29 02:52:29 UTC — npm-support replaces the package with a
0.0.1-securityholder; OSSF publishesMAL-2026-6467.
Affected packages (1)
- npm
@vpms/design-system0.1.31.0.01.0.11.1.2
Impact
- Install-time credential harvest —
preinstalllifecycle hook runs before any user code onnpm install, iteratesprocess.env, and exfiltrates every variable whose name contains the substringsSECRET,TOKEN,PASSWORD,KEY, orCREDENTIALto an attacker-controlled Pipedream HTTPS endpoint - Companion harvest of host identifiers (
os.hostname(),os.userInfo(), full process argv) lets the operator correlate stolen env vars to the specific developer machine or CI runner that produced them, enabling targeted re-use - Dependency-confusion vector — the
@vpmsscope was being squatted in the public npm registry to intercept builds that resolve@vpms/design-systemwithout an enforced scope-to-registry pin, so internal CI / private-registry consumers of a real@vpmspackage were the intended victims - Package masquerades as a "pentest design system"; the README contains no design-system functionality and the entire shipped tarball is the preinstall exfiltration primitive
What to do
- 1Remove every reference to
@vpms/design-systemfrompackage.json/ lockfiles / CI image layers; the name now serves a0.0.1-securityholder, so previously-pinned0.1.3/1.0.0/1.0.1/1.1.2no longer resolve - 2If your organization legitimately uses an internal
@vpmsscope: enforce a scope-to-registry pin (@vpms:registry=https://internal-registry.example.comin.npmrc) so the public registry is never consulted for that scope on any developer machine or CI runner - 3Treat any host that ran
npm installagainst@vpms/design-systemas having exfiltrated every*SECRET*/*TOKEN*/*PASSWORD*/*KEY*/*CREDENTIAL*environment variable: rotate npm tokens, GitHub Actions tokens, AWS / GCP / Azure tokens, SSH passphrases, database passwords, and any third-party API keys reachable from that runtime, from a separate clean device - 4Block
*.m.pipedream.netat egress for CI runners and developer endpoints; hunt firewall and DNS logs for outbound HTTPS toeov0bmnid410yqf.m.pipedream.netsince 2026-06-25 - 5Audit other
@vpms-scoped names in the public registry — the operator may publish additional siblings under the same scope to widen the dependency-confusion blast radius