Feed
HighPublished 24 Jul 202610 packages · 90 versions

GitHub Advisory malware sweep — 10-package `svelte-*-streak` / `eth-*` typosquat cluster (`eth-base` / `eth-slint` / `eth-codergen` / `streak-lib-math` / `svelte-streak-metrics`), `chai-as-stringify` `chai` v7 typosquat, `svgcraft-core` 8-version dropper, and `yuinpm` 68-version prolific-publisher cluster swept 2026-07-23 late-batch

Summary

On 2026-07-23 15:39 → 20:10 UTC GitHub retired 10 additional npm CWE-506 malware advisories in a later batch beyond the earlier 19-package sweep. Five clusters: 4-package streak-* / svelte-*-streak extending the 2026-07-21 wave; 3-package eth-* Ethereum typosquat; chai-as-stringify v7 typosquat; 8-version svgcraft-core dropper; and yuinpm — 68 date-tagged malicious versions.

typosquatcrypto-wallet-draincredential-theft
Detected by
GitHub Advisory Database · npm Security
Also known as
2026-07-23 GHSA npm late-batch sweep · streak-svelte cluster wave 2 · eth-* Ethereum typosquat cluster
Ecosystems
npm
Packages tracked
10

What happened

On 2026-07-23 GitHub's Advisory Database completed a later-batch of CWE-506 npm malware take-downs, adding 10 packages beyond the 19-package batch already captured by the sibling npm-2026-07-23-ghsa-malware-sweep module. The later batch was security-replaced across a wider window — 2026-07-23 15:39 UTC → 20:10 UTC — with the 4-package streak-* cluster taken down first, followed by yuinpm at 18:47, chai-as-stringify at 19:00, and the eth-* cluster spread across 18:27 → 20:10 UTC. All 10 records use the standard "any computer that has this package installed or running should be considered fully compromised — rotate all secrets from a different computer" boilerplate.

Cluster 1 — streak-* / svelte-*-streak micro-burst (4 packages)

| Package | Version | Publish (UTC) | npm security-replace (UTC) | |---|---|---|---| | streak-lib-math | 1.0.0 | 2026-07-23 10:32:23 | 2026-07-23 15:41:17 | | svelte-streak-metrics | 1.0.0 | 2026-07-23 10:32:41 | 2026-07-23 15:41:24 | | streak-bucket-lib | 1.0.0 | 2026-07-23 13:02:23 | 2026-07-23 15:39:50 | | svelte-goal-streak | 1.0.0 | 2026-07-23 13:02:41 | 2026-07-23 15:39:55 |

The pattern is unmistakable — two publish-bursts 2.5 hours apart, each with a streak-* and svelte-*-streak name published 18 seconds apart. Both 1.0.0-only, no version cranking, indicating single-shot payload deployments. This cluster is a direct continuation of the 2026-07-21 streak-daycount / svelte-streaks / streak-calendar sweep (see the npm-2026-07-21-ghsa-malware-sweep module) — same naming vocabulary (habit-tracker "streak" + Svelte), same take-down cadence.

Cluster 2 — eth-* Ethereum-typosquat cluster (3 packages)

| Package | Versions | Publish window (UTC) | npm security-replace (UTC) | |---|---|---|---| | eth-base | 1.0.0 | 2026-07-10 19:09:56 | 2026-07-23 20:10:08 | | eth-codergen | 1.0.01.0.2 (3 versions) | 2026-07-20 15:06 → 2026-07-23 17:26 | 2026-07-23 18:27:29 | | eth-slint | 1.0.0 | 2026-07-23 19:10:31 | 2026-07-23 20:10:14 |

eth-slint has the shortest publish→take-down window on record for this sweep — exactly 60 minutes. eth-codergen's three-version cadence (with 1.0.2 published just an hour before take-down) suggests the attacker was actively re-dropping after 1.0.1 was flagged. eth-base had the longest dormancy — nearly 13 days on the registry — which is unfortunately typical for typosquat malware in low-traffic name-spaces.

Cluster 3 — chai-as-stringify (chai v7 typosquat)

| Package | Versions | Publish window (UTC) | npm security-replace (UTC) | |---|---|---|---| | chai-as-stringify | 7.0.1, 7.0.2 | 2026-07-21 09:46:31 → 2026-07-22 01:55:40 | 2026-07-23 19:00:02 |

The 7.0.x version numbers precisely match the current chai major-version line — an intentional choice to make the package appear semver-compatible with legitimate Chai plugins like chai-as-promised. Chai is a top-tier JS assertion library, and chai-as-promised is one of its most common companions — a chai-as-stringify typo is high-probability across the tens of millions of test suites that use Chai.

Cluster 4 — svgcraft-core (8-version dropper)

| Package | Versions | Publish window (UTC) | npm security-replace (UTC) | |---|---|---|---| | svgcraft-core | 1.0.01.0.7 (8 versions) | 2026-07-01 16:47:35 → 2026-07-23 17:42:05 | 2026-07-23 18:32:35 |

Eight versions across 23 days, with rapid iteration in the first day (5 versions in the first hour) then slower drops. The last version (1.0.7) was published just 50 minutes before the security-replacement — a common pattern where the attacker realises the account is being flagged and drops a final version before losing publish access.

Cluster 5 — yuinpm (68-version prolific publisher)

| Package | Versions | Publish window (UTC) | npm security-replace (UTC) | |---|---|---|---| | yuinpm | 68 versions: 2026.7.19-22026.7.22-1-24 | 2026-07-19 03:38:11 → 2026-07-23 18:38:02 | 2026-07-23 18:47:22 |

The date-encoded semver tags (2026.7.19-2, 2026.7.20-1-N, 2026.7.22-1-N) are the signature of an automated version-cranking script — 34 versions of 2026.7.20-1-* alone in a single day. The final version (2026.7.22-1-24) was published just 9 minutes before take-down, again fitting the last-minute-drop pattern. The name has no clear typosquat target — anyone with yuinpm in a lockfile pulled it intentionally, so the vector is either a compromised maintainer of a downstream package or a deliberate test / research artifact that leaked into production.

Registry state

All 10 packages were npm-security-replaced (0.0.1-security sentinel tarball at latest dist-tag). Original version tarballs are no longer resolvable on the public registry, but private registry mirrors that cached the tarballs during the publish windows WILL keep serving the original versions after the public yank — any lockfile hit must be treated as actionable regardless of what the public registry currently returns.

Affected packages (10)

  • npmchai-as-stringify
    7.0.17.0.2
  • npmeth-base
    1.0.0
  • npmeth-codergen
    1.0.01.0.11.0.2
  • npmeth-slint
    1.0.0
  • npmstreak-bucket-lib
    1.0.0
  • npmstreak-lib-math
    1.0.0
  • npmsvelte-goal-streak
    1.0.0
  • npmsvelte-streak-metrics
    1.0.0
  • npmsvgcraft-core
    1.0.01.0.11.0.21.0.31.0.41.0.51.0.61.0.7
  • npmyuinpm
    2026.7.19-22026.7.19-2-12026.7.19-2-22026.7.19-2-32026.7.19-2-42026.7.19-2-52026.7.19-2-62026.7.19-2-72026.7.19-2-82026.7.19-2-92026.7.19-2-102026.7.19-2-112026.7.19-2-122026.7.20-1-12026.7.20-1-22026.7.20-1-32026.7.20-1-42026.7.20-1-52026.7.20-1-62026.7.20-1-72026.7.20-1-82026.7.20-1-92026.7.20-1-102026.7.20-1-112026.7.20-1-122026.7.20-1-132026.7.20-1-142026.7.20-1-152026.7.20-1-162026.7.20-1-172026.7.20-1-182026.7.20-1-192026.7.20-1-202026.7.20-1-212026.7.20-1-222026.7.20-1-232026.7.20-1-242026.7.20-1-252026.7.20-1-262026.7.20-1-272026.7.20-1-282026.7.20-1-292026.7.20-1-302026.7.20-1-312026.7.20-1-322026.7.20-1-332026.7.20-1-342026.7.22-1-12026.7.22-1-22026.7.22-1-32026.7.22-1-42026.7.22-1-52026.7.22-1-62026.7.22-1-72026.7.22-1-82026.7.22-1-92026.7.22-1-102026.7.22-1-112026.7.22-1-122026.7.22-1-132026.7.22-1-142026.7.22-1-152026.7.22-1-162026.7.22-1-172026.7.22-1-182026.7.22-1-192026.7.22-1-202026.7.22-1-212026.7.22-1-222026.7.22-1-232026.7.22-1-24

Impact

  • Any host that installed any of the packages 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
  • *`streak- / svelte--streak` micro-burst cluster* (4 packages): streak-lib-math@1.0.0 (published 2026-07-23 10:32:23 UTC), svelte-streak-metrics@1.0.0 (published 2026-07-23 10:32:41 UTC — 18 seconds after streak-lib-math), streak-bucket-lib@1.0.0 (published 2026-07-23 13:02:23 UTC), svelte-goal-streak@1.0.0 (published 2026-07-23 13:02:41 UTC — 18 seconds after streak-bucket-lib). The 18-second inter-publish gap across two 2.5-hour-separated bursts is a signature of automated same-account publishing. GitHub security-replaced all four within a 90-second window at 2026-07-23 15:39:50 → 15:41:24 UTC. This cluster extends the 2026-07-21 streak-daycount / svelte-streaks / streak-calendar campaign covered by the npm-2026-07-21-ghsa-malware-sweep module — same naming pattern (Svelte + habit-tracker/streak vocabulary), same single-1.0.0-version signature, same rapid publish-detect-replace pipeline
  • *`eth- Ethereum-typosquat cluster** (3 packages): eth-base@1.0.0 (published 2026-07-10 19:09:56 UTC, dormant ~13 days), eth-codergen@1.0.0 / 1.0.1 (published 2026-07-20 15:06 → 15:58 UTC) and eth-codergen@1.0.2 (published 2026-07-23 17:26:07 UTC — likely a re-drop after prior versions were detected), eth-slint@1.0.0 (published 2026-07-23 19:10:31 UTC — security-replaced exactly 60 minutes later at 20:10:14 UTC). The eth-* names ape common Ethereum-tooling prefixes; eth-codergen in particular typosquats code-generator tooling and eth-slint typosquats linting tooling. Any Ethereum-dev host that pulled these — especially between 2026-07-10 (when eth-base` first landed) and 2026-07-23 (take-down) — should be treated as wallet-compromised
  • chai-as-stringify chai v7 typosquat: versions 7.0.1 (published 2026-07-21 09:46:31 UTC) and 7.0.2 (published 2026-07-22 01:55:40 UTC), security-replaced 2026-07-23 19:00:02 UTC. The choice of 7.0.x version numbers precisely matches the current chai major-version line, and the name mimics the popular chai-as-promised extension — anyone semver-installing chai-as-promised from a lockfile refresh (with a typo) between 2026-07-21 and 2026-07-23 (~60 hours of exposure) is affected. Chai is a top-tier JS assertion library shipped in millions of test suites
  • svgcraft-core 8-version dropper: 8 malicious versions (1.0.01.0.7) published across 2026-07-01 16:47 UTC → 2026-07-23 17:42 UTC — nearly 23 days of exposure. The last version (1.0.7) was published just 50 minutes before the security-replacement. The svgcraft-core name typosquats generic SVG-tooling packages; the 23-day dormancy means downstream builds may have baked cached copies into node_modules snapshots long before the yank
  • yuinpm 68-version prolific-publisher: 68 malicious versions across a 4-day publish window (2026-07-19 03:38 UTC → 2026-07-23 18:38 UTC) using date-encoded semver tags of the form 2026.7.19-2, 2026.7.20-1-N, 2026.7.22-1-N. The prolific version-tag pattern (34 versions of 2026.7.20-1-* alone) is a signature of an automated version-cranking script. Security-replaced 2026-07-23 18:47:22 UTC — the actor published 2026.7.22-1-24 just 9 minutes before the take-down. The name is a phonetic play — no direct upstream to typosquat, but any lockfile hit is by definition intentional (nobody accidentally depends on yuinpm) so the pull represents targeted installation
  • None of the 10 packages have surviving version tarballs on the public npm registry — all replaced with 0.0.1-security sentinel tarballs. Private registry mirrors (Verdaccio, Artifactory, Nexus) that cached the tarballs during the publish windows WILL keep serving the original versions after the public yank — lockfile hits on these names must be treated as actionable regardless of what the public registry currently returns

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 you had any `streak- or svelte--streak` package in a lockfile*: cross-check whether you were also exposed to streak-daycount, svelte-streaks, or streak-calendar from the 2026-07-21 sweep — the naming convention and single-1.0.0-version signature strongly suggest the same operator. Rotate CI credentials for any Svelte build that ran a lockfile refresh between 2026-07-23 10:32 UTC and the 15:41 UTC take-down (~5 hours of exposure)
  3. 3*If you had any `eth- package in a lockfile** (eth-base, eth-codergen, eth-slint): treat as a wallet-compromise event. Rotate every crypto wallet key, seed phrase, and hardware-wallet PIN accessible from the dev host. eth-base in particular has been on the registry since 2026-07-10 — nearly two weeks of exposure — long enough for many builds to have baked it into cached node_modules` snapshots or CI containers. Move funds via a clean device before attempting rotation
  4. 4If you had chai-as-stringify in a lockfile: check whether the intended dependency was chai-as-promised (correct name for the Chai promise-assertion extension) — this is a canonical typosquat. Both 7.0.1 and 7.0.2 are compromised. Audit test-suite build logs for npm install runs on 2026-07-21 09:46 UTC → 2026-07-23 19:00 UTC (~57 hours of exposure)
  5. 5If you had svgcraft-core in a lockfile: any of the 8 versions (1.0.01.0.7) published across 2026-07-01 → 2026-07-23 is compromised. The 23-day exposure window means downstream builds may have baked this into cached node_modules snapshots long before the yank; grep every CI container image built in July 2026 for the package
  6. 6If you had yuinpm in a lockfile: any of the 68 versions is compromised. The date-encoded version tags mean semver ranges like ^2026.7.19-2 or >=2026.7.0 would have pulled multiple malicious versions across the 4-day window. This is not a typosquat of a legitimate name — a lockfile hit indicates intentional pulling of an attacker-controlled package, so audit human commits that added this dependency
  7. 7Verify none of the 10 listed packages still resolves via your private mirror — internal Artifactory / Nexus / Verdaccio instances routinely cache tarballs and will keep serving the original versions after the public yank
  8. 8For projects using postinstall-scripting packages, consider running npm install --ignore-scripts in CI as a defense-in-depth measure and re-invoking scripts only for vetted first-party packages

References

npm-2026-07-24-ghsa-malware-sweep