Feed
HighPublished 13 Jul 202614 packages · 20 versions

GitHub Advisory malware sweep — 14 npm packages (10-package `getd-*` / `get*` 40-day Spanish-enterprise sleeper cluster, `pure-folder-three` poisoned bump, `dotnet-runtime-base` fresh burst, `node-sysmetrics`, `@jplopezy/connectivity-test-do-not-install`) retired 2026-07-13

Summary

On 2026-07-13 GitHub's Advisory Database retired 14 CWE-506 npm malware advisories. The main event is a 10-package getd-* / get* Spanish-enterprise dep-confusion sleeper cluster (all 0.0.1 published in a 22-second burst 2026-06-03 13:48–13:49 UTC, dormant for 40 days, then retired in a 47-second take-down burst at 04:51–04:52 UTC). Also included: a maintainer-takeover-style poisoned bump on pure-folder-three@0.7.3, dotnet-runtime-base@{1.0.4,1.0.5} in a same-day fresh burst, node-sysmetrics@1.0.0, and @jplopezy/connectivity-test-do-not-install.

dependency-confusiondormant-domaintyposquatmaintainer-takeovercredential-theft
Detected by
GitHub Advisory Database · npm Security
Also known as
2026-07-13 GHSA npm sweep · getd Spanish-enterprise sleeper cluster
Ecosystems
npm
Packages tracked
14

What happened

On 2026-07-13 GitHub's Advisory Database published 14 CWE-506 (Embedded Malicious Code) advisories against npm packages. Every record uses the standard "any computer that has this package installed or running should be considered fully compromised — rotate all secrets from a different computer" boilerplate. No payload write-ups accompany the GHSA texts, so defenders should treat install-time behavior as unanalyzed and assume worst case for any host that resolved these names. Registry cross-reference against the npm time map revealed sharply distinct clusters:

Cluster 1 — Spanish-enterprise dep-confusion 40-day sleeper (10 packages)

| Package | 0.0.1 publish (UTC) | 0.0.1-security replacement (UTC) | |---|---|---| | getd-content-management | 2026-06-03 13:48:49 | 2026-07-13 04:51:47 | | getd-eslint-rules | 2026-06-03 13:48:51 | 2026-07-13 04:51:52 | | getd-handler-api | 2026-06-03 13:48:54 | 2026-07-13 04:51:57 | | getd-pantallas-cliente | 2026-06-03 13:48:56 | 2026-07-13 04:52:03 | | getd-transactional-web | 2026-06-03 13:48:58 | 2026-07-13 04:52:08 | | getd-typescript-eslint-rules | 2026-06-03 13:48:58 | 2026-07-13 04:52:08 | | getd-web-corporativa | 2026-06-03 13:49:05 | 2026-07-13 04:52:22 | | getd-ui-library | 2026-06-03 13:49:02 | 2026-07-13 04:52:17 | | getui-library | 2026-06-03 13:49:11 | 2026-07-13 04:52:34 | | gethandler-api | 2026-06-03 13:49:09 | 2026-07-13 04:52:27 |

Every package in the cluster:

  • Shipped exactly 0.0.1 — the "just enough to exist" version pin, distinct from the 99.9.1 race pin the 2026-07-07 Higher Logic / AT&T eBiz / Amtrav cluster used. 0.0.1 reads as normal for an internal-first release; a semver resolver against a scope-pinned internal package will still fall through and match this if the internal registry lookup fails.
  • Landed in a 22-second publish burst on 2026-06-03 13:48:49 → 13:49:11 UTC — the fingerprint of one operator running a shared publish script through a name list.
  • Sat live for 40 days — no visible take-down attempt between 2026-06-03 and 2026-07-13. This is deliberate ambient dormancy: the names get indexed by internal-registry scanners, cached by pre-warm pipelines, and become "background noise" that a defender running a fresh sweep in July would be more likely to trust than a same-day upload.
  • Retired in a 47-second take-down burst on 2026-07-13 04:51:47 → 04:52:34 UTC — coordinated 0.0.1-security replacement across all 10 packages, then GHSA advisories published together.

Target attribution

The Spanish-language slugs (web-corporativa = "corporate web", pantallas-cliente = "client screens", transactional-web = internal-facing English shape common in Spanish-language dev teams, content-management = CMS) plus the getd-* prefix (reads as get-d[ata] or a specific-org three-letter code) strongly suggest a targeted dep-confusion campaign against a specific Spanish-speaking enterprise's internal npm registry namespace. The mix of eslint plugin rules (getd-typescript-eslint-rules, getd-eslint-rules), UI libraries (getd-ui-library, getui-library), API handlers (getd-handler-api, gethandler-api), and CMS/content packages is exactly the shape of a large Node.js monolith at one enterprise — a typical microservice / component split across 10 internal packages.

No public write-up from Socket / JFrog / Aikido / Snyk / Phylum accompanies these advisories at time of write; the retirement was driven by npm Security's internal review, feeding into GHSA.

Cluster 2 — pure-folder-three poisoned bump (1 package)

pure-folder-three was published as 0.5.0 on 2026-02-04 13:00:48 UTC, then 0.6.0, 0.7.0, 0.7.1 (2026-02-27 20:27:40 UTC). The account then went dormant for over 4 months until a poisoned 0.7.3 on 2026-07-12 13:29:35 UTC — retired 2026-07-13 01:52:56 UTC.

The advisory covers 0.5.0, 0.6.0, 0.7.0, 0.7.1, 0.7.3 as compromised. Because we cannot confirm from the advisory text whether the earlier versions were genuinely legitimate or whether the account was compromised from the beginning, the safe assumption for defenders is that ALL five listed versions are malicious.

This is the shape of a dormant maintainer-account takeover → poisoned bump: the operator sits on a real-looking package with a real-looking version history for months, then pushes a poisoned bump inside a plausible semver range so any downstream project with ^0.5.0 or ~0.7 resolves the malicious version on the next npm install.

Cluster 3 — dotnet-runtime-base fresh burst (1 package, 2 versions)

dotnet-runtime-base@1.0.4 was published 2026-07-11 11:40:14 UTC (same day as the jscrambler compromise and the July 11 GHSA sweep). 1.0.5 followed on 2026-07-12 07:08:14 UTC. Both retired 2026-07-13 01:19:04 UTC.

The name shape targets developers looking for a .NET runtime helper on npm. There is no legitimate first-party dotnet-runtime-base package — Microsoft distributes the .NET runtime as a native installer, not via npm. Any hit on this name in an npm lockfile is a supply-chain incident.

Cluster 4 — node-sysmetrics@1.0.0 (1 package)

node-sysmetrics@1.0.0 was published 2026-07-12 23:53:34 UTC, 1.0.1 at 2026-07-13 00:15:21 UTC. The 1.0.1 was unpublished by the publisher at 01:04:17 UTC — a self-erasure attempt likely to hide activity before npm Security took visible action. GHSA advisory was published 2026-07-13. The canonical Node.js system-metrics packages are systeminformation and node-os-utils; node-sysmetrics has no legitimate parent.

Cluster 5 — @jplopezy/connectivity-test-do-not-install (1 package)

@jplopezy/connectivity-test-do-not-install — earliest observed release was 0.0.0-test on 2026-06-01 14:14:45 UTC. Replaced with 0.0.1-security on 2026-07-13 04:52:44 UTC. The self-labeled "do-not-install" slug is unusual: it matches the shape researchers occasionally use to publish safe canary packages that they explicitly warn callers off of. Whether this is a researcher canary that GHSA over-flagged or an actual malicious drop with a taunt-shaped name is unclear from the advisory text alone. GHSA classifies it as embedded malware; defenders should treat any lockfile hit as an incident.

Contrast with recent sweeps

| Date | Packages | Notes | |---|---|---| | 2026-07-06 | ~155 | Largest 2026 sweep | | 2026-07-07 | ~65 | AI-SDK typosquats + Solana base58 | | 2026-07-08 | ~20 | Claude-Code typosquat cluster | | 2026-07-10 (early) | 25 | Epic Games / LuminaryCloud / Voyager dep-confusion + nodemon family | | 2026-07-10 (late) / 2026-07-11 | 11 | Higher Logic / AT&T eBiz / Amtrav / babel-eslint dep-confusion + type-* 3.3.7 cluster + auth-typosquats | | 2026-07-13 | 14 | *Spanish-enterprise `getd- 40-day sleeper cluster (10) + pure-folder-three poisoned bump + dotnet-runtime-base + node-sysmetrics + @jplopezy/connectivity-test-do-not-install`** |

The running July 1–13 npm-malware retirement count is ~320 packages across 10 GHSA sweeps.

Registry state

Every package now resolves to a 0.0.1-security holding tarball owned by npm Security. Historical version tarballs may remain fetchable from the CDN for 24–72 hours after the security replacement lands and should be treated as live malware in any lockfile hit — regardless of exact version. Because the security replacement wipes the historical version list from the public registry response, the version list below records 0.0.1 for the sleeper cluster (the observed pre-replacement version) and each concrete version for the fresh-burst clusters.

Affected packages (14)

  • npm@jplopezy/connectivity-test-do-not-install
    0.0.0-test
  • npmdotnet-runtime-base
    1.0.41.0.5
  • npmgetd-content-management
    0.0.1
  • npmgetd-eslint-rules
    0.0.1
  • npmgetd-handler-api
    0.0.1
  • npmgetd-pantallas-cliente
    0.0.1
  • npmgetd-transactional-web
    0.0.1
  • npmgetd-typescript-eslint-rules
    0.0.1
  • npmgetd-ui-library
    0.0.1
  • npmgetd-web-corporativa
    0.0.1
  • npmgethandler-api
    0.0.1
  • npmgetui-library
    0.0.1
  • npmnode-sysmetrics
    1.0.01.0.1
  • npmpure-folder-three
    0.5.00.6.00.7.00.7.10.7.3

Impact

  • Any host that installed any of the 14 packages listed below should be treated as fully compromised — every GHSA record uses the boilerplate CWE-506 "rotate all secrets from a different computer" language, and no patched version exists for any of them
  • Spanish-enterprise dep-confusion sleeper cluster (10 packages): getd-typescript-eslint-rules, getd-eslint-rules, getd-transactional-web, getd-web-corporativa, getd-pantallas-cliente, getd-ui-library, getui-library, getd-handler-api, gethandler-api, getd-content-management — all shipped exactly 0.0.1 in a 22-second publish burst 2026-06-03 13:48:49–13:49:11 UTC and retired together in a 47-second take-down burst 2026-07-13 04:51:47–04:52:34 UTC. The Spanish-language slugs (web-corporativa, pantallas-cliente, transactional-web, content-management) plus the internal-scope-shape naming (getd-* reads as a get-d[ata] or single-org prefix) point to a targeted dep-confusion campaign against a specific Spanish-speaking enterprise's internal registry namespace. 40-day dormancy between publish and retirement is a deliberate ambient technique — the operator wanted the names to become "background noise" in any internal registry indexer before the actual malicious behavior triggers, and to survive first-pass detection sweeps that focus on recently-published packages
  • pure-folder-three poisoned bump (1 package): pre-existing legitimate-looking package with a normal version history (0.5.0, 0.6.0, 0.7.0, 0.7.1 all published 2026-02-04 to 2026-02-27) — then a poisoned 0.7.3 bump on 2026-07-12 13:29:35 UTC that lived for ~12 hours before retirement 2026-07-13 01:52:56 UTC. Any project pinning ^0.5.0, ~0.7, or any range that includes 0.7.3 would have resolved the malicious bump. Downstream consumers can't rely on a semver upper bound below 0.7.3 since the legitimate maintainer window ended at 0.7.1. This is a classic dormant-account takeover → poisoned bump signature — the earlier versions may have been genuine and the account has since been compromised, or the whole package was seeded 5 months in advance to sit dormant before the poisoned bump
  • dotnet-runtime-base fresh burst (1 package, 2 versions): 1.0.4 published 2026-07-11 11:40:14 UTC then 1.0.5 published 2026-07-12 07:08:14 UTC. Both retired 2026-07-13 01:19:04 UTC. Same-week take-down; the package name is a plausible-sounding .NET runtime typo shape but note that dotnet-runtime and @microsoft/dotnet-runtime naming spaces do not have a public first-party npm namesake — the target is anyone using .NET tooling that npm-installs anything under a dotnet-* prefix
  • node-sysmetrics@1.0.0 — throwaway typosquat published 2026-07-12 23:53:34 UTC, retired 2026-07-13. The maintainer bumped to 1.0.1 at 00:15:21 UTC and then unpublished it at 01:04:17 UTC (self-erasure) before npm Security replaced. Targets any project searching for a Node.js system-metrics helper; the shape overlaps with legitimate metric-collection packages like systeminformation and node-os-utils
  • @jplopezy/connectivity-test-do-not-install — this one is unusual: the package name literally reads "do-not-install" (matching the tagged-warning pattern researchers occasionally use to publish safe canaries). The publisher had an earlier 0.0.0-test release on 2026-06-01. Whether this is a researcher canary that got flagged or a live drop with a taunt-shaped slug is unclear from the advisory, but GHSA treats it as embedded malware and defenders should as well
  • No payload write-up accompanies the GHSA texts — defenders should treat install-time behavior as unanalyzed and assume worst case for any host that resolved these names

What to do

  1. 1Grep every lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml) for each name in the packages map below. Any match is a supply-chain incident: rotate every credential the build runner could reach and re-image the build host
  2. 2*If your organization runs a Spanish-language internal npm registry and uses a `getd- or getui-` scope for internal tooling: this cluster is a dep-confusion campaign against your namespace. Audit every internal Node.js project for imports of any name in Cluster 1 below. Register the `getd- and getui-* names on the public registry as defensive stubs, and route internal names via .npmrc scope pinning (e.g. @yourorg:registry=https://internal/`) or unscoped-package pinning so the public registry path is never queried for these names
  3. 3If you had pure-folder-three in a lockfile: pin to <=0.7.1 (last confirmed-legitimate maintainer window) or remove the dependency entirely. The 0.7.3 bump is the poisoned release; the earlier 0.5.00.7.1 versions were published by what appears to be the legitimate maintainer window but should still be audited if you're sensitive to a full account takeover having occurred earlier
  4. 4If you had dotnet-runtime-base in a lockfile: there is no legitimate first-party dotnet-runtime-base npm package. Remove the dependency; the canonical .NET runtime is distributed by Microsoft as a native installer (dotnet.microsoft.com), not via npm
  5. 5If you had node-sysmetrics in a lockfile: the canonical Node.js system-metrics packages are systeminformation and node-os-utils; node-sysmetrics has no legitimate parent
  6. 6For @jplopezy/connectivity-test-do-not-install: no legitimate use case for a package with "do-not-install" in the name; treat any lockfile match as an incident and remove
  7. 7Verify none of the 14 listed packages still resolves via your private mirror — internal Artifactory / Nexus / Verdaccio instances routinely cache tarballs and will keep serving the malicious versions after the public yank, especially with the 40-day dormancy window in Cluster 1 giving them time to be cached in scanning pipelines that pre-warm on publish
  8. 8Because the getd-* cluster sat dormant for 40 days before retirement, any internal-registry mirror set to pre-cache "trending" or "recently-observed" npm names likely has the malicious tarballs cached today. Explicitly evict getd-* and getui-library / gethandler-api names from every internal cache

References

npm-2026-07-13-ghsa-malware-sweep