September 2025 npm compromise
On 15 September 2025 the npm account that publishes the art-ws packages was compromised in the Shai-Hulud worm campaign. Forty-five versions of twenty packages were published with malicious code, in two automated bursts: twenty packages in seven and a half seconds at 05:21 UTC, the rest at 08:52–08:58 UTC. The npm registry still holds the timestamps of the removed versions, so you can reconstruct this yourself rather than take our word for it.
All forty-five versions were removed from npm by the registry's security team. You cannot install them. Every affected package has exactly one compromised release window, September 2025 — the second Shai-Hulud wave in November 2025 did not touch these packages. Last verified against the npm registry on 14 August 2026.
We were not the target. Over two hundred npm packages were hit the same week, and you can confirm that in thirty seconds from sources that have nothing to do with us. That is context, not a defence. What follows is what happened to ours.
What was affected
Twenty of the thirty-six packages published by the account.
Packages with a clean version above the compromise
Upgrade to this version or later.
| Package | Removed versions | Clean version |
|---|---|---|
@art-ws/di | 2.0.28, 2.0.32 | 2.0.42 |
@art-ws/common | 2.0.22, 2.0.28 | 2.0.41 |
@art-ws/slf | 2.0.15, 2.0.22 | 2.0.41 |
@art-ws/http-server | 2.0.21, 2.0.24, 2.0.25 | 2.0.41 |
@art-ws/db-context | 2.0.21, 2.0.24 | 2.0.42 |
@art-ws/fastify-http-server | 2.0.24, 2.0.26, 2.0.27 | 2.0.41 |
@art-ws/di-node | 2.0.13, 2.0.14, 2.0.15, 2.0.18 | 2.0.41 |
@art-ws/config-ts | 2.0.7, 2.0.8 | 2.0.9 |
@art-ws/config-eslint | 2.0.4, 2.0.5 | 2.0.7 |
@art-ws/openapi | 0.1.9, 0.1.11, 0.1.12 | 0.1.41 |
Packages where the newest release is older than the compromise
For these ten, the last version we published predates the attack. It is clean, but its number is lower than the removed ones, so an automated scanner reports “no fixed version available”. That report is accurate. Each of these packages will get either a clean release above the malicious versions or an explicit deprecation notice pointing to this page. We are not putting a date on that here.
| Package | Removed versions | Newest published |
|---|---|---|
ngx-ws | 1.1.5, 1.1.6 | 1.1.4 |
@art-ws/ssl-info | 1.0.9, 1.0.10 | 1.0.8 |
db-evo | 1.1.4, 1.1.5 | 1.1.3 |
@art-ws/eslint | 1.0.5, 1.0.6 | 1.0.4 |
ng-imports-checker | 0.0.9, 0.0.10 | 0.0.8 |
@art-ws/package-base | 1.0.5, 1.0.6 | 1.0.4 |
@art-ws/prettier | 1.0.5, 1.0.6 | 1.0.4 |
@art-ws/web-app | 1.0.3, 1.0.4 | 1.0.2 |
ts-imports | 1.0.1, 1.0.2 | 1.0.0 |
pm2-gelf-json | 1.0.4, 1.0.5 | 1.0.3 |
The other sixteen packages of the account were not affected.
The tables above list all forty-five versions. Each affected package has one advisory identifier in the MAL-2025-47… range; npm removed every one of these versions from the registry.
What happened next
We did not remove the malicious versions — npm did, and we found out the hard way.
- 15 September 2025 — the malicious versions are published.
- Around 18–19 September — the account stops working. No sign-in, no password reset, packages missing. We received no notice before that.
- 20 September — we open a support request, and we publish emergency copies of seven packages under a separate
@art-ws.orgscope so that our own builds keep working while the account is locked. Those copies are still on npm; see below. - 22 September — npm replies: the account was disabled while they resolved the incident and removed the compromised versions, and it has now been reinstated.
- 25 September — we enable two-factor authentication on the account.
- August 2026 — we re-check the whole account against the OSV database and the npm registry rather than from memory. That is where the number twenty comes from — not from the two packages someone reported to us.
The account is under our control and has not been hit again through three later waves of the same campaign, including Shai-Hulud 2.0 in November 2025.
About the @art-ws.org packages
Seven packages under the @art-ws.org scope were published on 20 September 2025. They are the emergency copies described above, made while the main account was locked, and they are kept as a fallback mirror. They are not part of the compromise. They are also not current — the @art-ws packages in the tables above are the ones to use.
Check it yourself
Do not take the tables above on trust. In your own project:
npm ls @art-ws/common @art-ws/config-eslint @art-ws/config-ts @art-ws/db-context \
@art-ws/di @art-ws/di-node @art-ws/eslint @art-ws/fastify-http-server \
@art-ws/http-server @art-ws/openapi @art-ws/package-base @art-ws/prettier \
@art-ws/slf @art-ws/ssl-info @art-ws/web-app \
db-evo ng-imports-checker ngx-ws pm2-gelf-json ts-importsCompare what it prints with the removed versions above. A match means a compromised release is pinned in your lockfile. This also catches our packages that reached you indirectly, as a dependency of something else. If you have none of them, npm ls prints (empty) and exits with a non-zero status — that is the expected result here, not an error.
npm audit works too, with one thing worth knowing before you run it: it reports every advisory it finds in your dependency tree, not only this incident. Findings unrelated to September 2025 will show up alongside, and they are a different conversation from this page.
What this does not prove. It tells you what your dependency tree resolves to now. It tells you nothing about a machine that installed one of those versions in September 2025. If that happened, treat that machine and every credential it could reach as exposed and follow the published guidance on the Shai-Hulud campaign — ours is not the report to rely on for that.
What is changing in how we publish
All thirty-six packages were published from a single npm account. That was one point of failure, and it is the one that was taken.
One package, @art-ws/teamai, is already published from CI with a provenance attestation — npm shows it on the package page, you do not have to believe us. The rest are moving to the same path. When a package gets there, the proof appears on npm, not in a sentence here.
Reporting a problem
Write to security@art-ws.org. Please include the package, the version, and what you did to trigger it.
Changelog
- 14 August 2026 — page published.