GitHub Advisory malware sweep — 4-package `app-data-*` / `app-node-*` v2.1.6 typosquat cluster (`app-data-layer`, `app-node-layer`, `app-data-ist`, `app-data-lts`) coordinated security-replace on 2026-07-24
On 2026-07-24 17:19:21 → 17:19:45 UTC (a 24-second window) GitHub retired 4 npm CWE-506 malware advisories for a tight app-*-prefixed typosquat/dependency-confusion cluster: app-data-layer, app-node-layer, app-data-ist, app-data-lts — all published as 2.1.6, all detected in a single coordinated pipeline sweep.
- Detected by
- GitHub Advisory Database · npm Security
- Also known as
- 2026-07-24 GHSA npm app-* cluster sweep · app-*-layer v2.1.6 cluster
- Ecosystems
- npm
- Packages tracked
- 4
What happened
On 2026-07-24 GitHub's Advisory Database security-replaced 4 npm packages in a coordinated 24-second window as CWE-506 (Embedded Malicious Code) malware. The tight coordination — and the uniform 2.1.6 version across all 4 packages — is the signature of a single-operator typosquat or dependency-confusion campaign targeting Adobe App Builder / AIO tooling or generic app-* internal-registry names.
Cluster — app-* v2.1.6 typosquat/dep-confusion (4 packages)
| Package | Version | Publish (UTC) | npm security-replace (UTC) | Time on registry | |---|---|---|---|---| | app-data-lts | 2.1.6 | 2026-07-20 17:56:09 | 2026-07-24 17:19:40 | ~3d 23h | | app-data-layer | 2.1.6 | 2026-07-20 21:32:20 | 2026-07-24 17:19:35 | ~3d 20h | | app-data-ist | 2.1.6 | 2026-07-21 04:38:11 | 2026-07-24 17:19:21 | ~3d 13h | | app-node-layer | 2.1.6 | 2026-07-24 16:40:37 | 2026-07-24 17:19:45 | ~39 minutes |
All four security-replacements landed within a 24-second window at 2026-07-24 17:19:21 → 17:19:45 UTC — the tightest coordinated take-down cadence recorded on any GHSA npm batch in July 2026. The GHSA IDs are:
GHSA-346c-3w9c-8pmh—app-data-layerGHSA-4xc7-2jx9-rp5j—app-node-layerGHSA-wcx6-x67q-wff5—app-data-istGHSA-c6xr-m3x3-23fm—app-data-lts
All 4 advisories 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.
Attribution signals
Naming pattern
The app-* prefix with -data-* / -node-* suffixes matches multiple internal-registry conventions:
- Adobe App Builder / AIO tooling: Adobe uses
@adobe/aio-*scopes canonically, butapp-*public names have been targeted before — the 2026-07-23 GHSA sweep capturedaio-commerce-lib-app@110.0.0as a dependency-confusion attempt against Adobe internal registries. This cluster may be the same operator returning with a typosquat-oriented variant (2.1.6rather than110.x) - Generic frontend/backend layer naming:
-data-layer,-node-layer,-data-lts(long-term support),-data-ist(installer/interstitial?) are all plausible internal names for a monorepo's data-access and Node runtime layers. Any organisation with a private monorepo using these names is vulnerable to dependency confusion
Version choice
The uniform 2.1.6 version across all 4 packages is unusual — it is neither the very-low 1.0.0 typical of throwaway typosquats nor the very-high 110.x / 22.x typical of dependency-confusion attacks. 2.1.6 is an intentional-looking mid-range version, consistent with the operator wanting the packages to appear mature (installers tend to pin to ^2.x rather than ^1.x, and semver ranges resolve 2.1.6 as the highest compatible for ^2.1.0).
Coordinated take-down
A 24-second security-replace window across 4 packages is not accidental — GitHub's malware pipeline batched these based on shared indicators (payload signature, publisher account, upload IP, or dependency graph). This is consistent with the 2-minute batching observed on the 2026-07-23 ethers-packge / @bcryptln/* crypto cluster.
Registry state
All 4 packages were npm-security-replaced (0.0.1-security sentinel tarball at latest dist-tag). Original 2.1.6 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 (4)
- npm
app-data-ist2.1.6 - npm
app-data-layer2.1.6 - npm
app-data-lts2.1.6 - npm
app-node-layer2.1.6
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
- *`app-
-prefixed 4-package cluster** — all2.1.6:app-data-layer@2.1.6(published 2026-07-20 21:32:20 UTC, ~4 days on the registry),app-data-lts@2.1.6(published 2026-07-20 17:56:09 UTC, ~4 days),app-data-ist@2.1.6(published 2026-07-21 04:38:11 UTC, ~3.5 days),app-node-layer@2.1.6` (published 2026-07-24 16:40:37 UTC — just 39 minutes before take-down). All four were security-replaced within a 24-second window at 2026-07-24 17:19:21 → 17:19:45 UTC — the tightest coordinated take-down cadence recorded on any GHSA npm batch this month, strongly indicating GitHub's malware pipeline flagged them as a single related campaign - The uniform
2.1.6version choice across all 4 packages, combined with theapp-prefix and matching-data-*/-node-*name suffixes, is consistent with either a typosquat (aping Adobe App Builder / AIO tooling — the previous 2026-07-23 sweep already flaggedaio-commerce-lib-appat110.0.0as a dependency-confusion attempt against Adobe internal registries) or dependency-confusion against genericapp-*internal registry names. Choosing2.1.6(an intentional-looking mid-range version) rather than the very-high dep-confusion pattern (110.x,22.x) suggests the operator was optimising for typosquat plausibility over registry-precedence app-node-layerhas the shortest publish→take-down window in the cluster — just 39 minutes on the registry (published 16:40:37 UTC, security-replaced 17:19:45 UTC). This mirrors the rapid detection-response window observed withvitest-axiosandfs-extra-corein the 2026-07-23 sweep (40-67 minutes each) and confirms GitHub's malware pipeline is catching same-day-published typosquats reliablyapp-data-layer,app-data-ist, andapp-data-ltshad 3.5-4 days on the registry each before take-down, which is enough time for automated dependency-refresh workflows (Renovate, Dependabot,npm audit fix, weekly CI lockfile updates) to have pulled the tarballs into build caches. Any Node.js project running such workflows against a package.json referencing a bareapp-data-*name should audit theirnode_modulessnapshots for the compromised2.1.6- None of the 4 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 ~4-day publish window 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 `app-data-
orapp-node-` package in a lockfile: verify whether the intended dependency is an Adobe App Builder / AIO internal-registry name (Adobe uses `@adobe/aio-scopes and theaio-prefix — theapp-*prefix used here is NOT the canonical Adobe naming, so any resolution against these public packages is a typosquat/dep-confusion event). Cross-check whether your project also hadaio-commerce-lib-app@110.0.0` from the 2026-07-23 sweep — the same operator may have used both naming variants - 3For any project targeting Adobe App Builder / AIO deployments: audit your CI/CD pipeline for these 4 package names, and configure your private registry mirror (Verdaccio, Artifactory, Nexus) with scoped resolution so that public packages cannot shadow internal names during a lockfile refresh
- 4Verify none of the 4 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. Any cached
2.1.6tarball must be purged from mirror caches - 5For 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 - 6If your build runners had access to Adobe I/O Runtime credentials, AWS/GCP metadata endpoints, or cloud storage keys during a lockfile refresh window that pulled any
app-*@2.1.6tarball: rotate those credentials from a clean workstation and audit access logs for exfiltration attempts to attacker-controlled endpoints during the exposure window
References
- GitHubGitHub Advisory Database — recent npm malware advisoriesgithub.com
- GitHubGHSA-346c-3w9c-8pmh — app-data-layer malware advisorygithub.com
- GitHubGHSA-4xc7-2jx9-rp5j — app-node-layer malware advisorygithub.com
- GitHubGHSA-wcx6-x67q-wff5 — app-data-ist malware advisorygithub.com
- GitHubGHSA-c6xr-m3x3-23fm — app-data-lts malware advisorygithub.com