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
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.
- 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.0 → 1.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.0 → 1.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-2 → 2026.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)
- npm
chai-as-stringify7.0.17.0.2 - npm
eth-base1.0.0 - npm
eth-codergen1.0.01.0.11.0.2 - npm
eth-slint1.0.0 - npm
streak-bucket-lib1.0.0 - npm
streak-lib-math1.0.0 - npm
svelte-goal-streak1.0.0 - npm
svelte-streak-metrics1.0.0 - npm
svgcraft-core1.0.01.0.11.0.21.0.31.0.41.0.51.0.61.0.7 - npm
yuinpm2026.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 afterstreak-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 afterstreak-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-21streak-daycount/svelte-streaks/streak-calendarcampaign covered by thenpm-2026-07-21-ghsa-malware-sweepmodule — 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) andeth-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). Theeth-*names ape common Ethereum-tooling prefixes;eth-codergenin particular typosquats code-generator tooling andeth-slinttyposquats linting tooling. Any Ethereum-dev host that pulled these — especially between 2026-07-10 (wheneth-base` first landed) and 2026-07-23 (take-down) — should be treated as wallet-compromised chai-as-stringifychaiv7 typosquat: versions7.0.1(published 2026-07-21 09:46:31 UTC) and7.0.2(published 2026-07-22 01:55:40 UTC), security-replaced 2026-07-23 19:00:02 UTC. The choice of7.0.xversion numbers precisely matches the currentchaimajor-version line, and the name mimics the popularchai-as-promisedextension — anyone semver-installingchai-as-promisedfrom 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 suitessvgcraft-core8-version dropper: 8 malicious versions (1.0.0→1.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. Thesvgcraft-corename typosquats generic SVG-tooling packages; the 23-day dormancy means downstream builds may have baked cached copies intonode_modulessnapshots long before the yankyuinpm68-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 form2026.7.19-2,2026.7.20-1-N,2026.7.22-1-N. The prolific version-tag pattern (34 versions of2026.7.20-1-*alone) is a signature of an automated version-cranking script. Security-replaced 2026-07-23 18:47:22 UTC — the actor published2026.7.22-1-24just 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 onyuinpm) 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-securitysentinel 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
- 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*If you had any `streak-
orsvelte--streak` package in a lockfile*: cross-check whether you were also exposed tostreak-daycount,svelte-streaks, orstreak-calendarfrom 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*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-basein 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 cachednode_modules` snapshots or CI containers. Move funds via a clean device before attempting rotation - 4If you had
chai-as-stringifyin a lockfile: check whether the intended dependency waschai-as-promised(correct name for the Chai promise-assertion extension) — this is a canonical typosquat. Both7.0.1and7.0.2are compromised. Audit test-suite build logs fornpm installruns on 2026-07-21 09:46 UTC → 2026-07-23 19:00 UTC (~57 hours of exposure) - 5If you had
svgcraft-corein a lockfile: any of the 8 versions (1.0.0→1.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 cachednode_modulessnapshots long before the yank; grep every CI container image built in July 2026 for the package - 6If you had
yuinpmin a lockfile: any of the 68 versions is compromised. The date-encoded version tags mean semver ranges like^2026.7.19-2or>=2026.7.0would 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 - 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
- 8For projects using
postinstall-scripting packages, consider runningnpm install --ignore-scriptsin CI as a defense-in-depth measure and re-invoking scripts only for vetted first-party packages
References
- GitHubGitHub Advisory Database — recent npm malware advisoriesgithub.com
- GitHubGHSA-c7rv-9j9g-pqh2 — streak-lib-math malware advisorygithub.com
- GitHubGHSA-fc4x-xfq3-5f35 — svelte-streak-metrics malware advisorygithub.com
- GitHubGHSA-rg2p-8587-wx3w — streak-bucket-lib malware advisorygithub.com
- GitHubGHSA-jw9g-wvg5-7rjg — svelte-goal-streak malware advisorygithub.com
- GitHubGHSA-26h4-2435-hp66 — eth-base malware advisorygithub.com
- GitHubGHSA-87w3-vjw9-8h4w — eth-codergen malware advisorygithub.com
- GitHubGHSA-xp97-c4c4-7928 — eth-slint malware advisorygithub.com
- GitHubGHSA-vh7h-h87g-qv6x — chai-as-stringify malware advisorygithub.com
- GitHubGHSA-j9vc-q728-qcx4 — svgcraft-core malware advisorygithub.com
- GitHubGHSA-vpgm-qmgp-w4h4 — yuinpm malware advisorygithub.com