AsyncAPI npm Packages Re-Compromised: @asyncapi/generator 3.3.1 and Three Others

Four packages in the @asyncapi npm scope were re-compromised on July 14, 2026, with new malicious versions published between approximately 07:10 and 08:30 UTC. All four were yanked from the registry before 09:00 UTC.
These packages were previously compromised in the November 2025 Shai-Hulud supply chain wave. The July 2026 event is a separate re-publish, not a continuation of the earlier incident. The compromised versions are new: 3.3.1 for @asyncapi/generator, 0.7.1 for @asyncapi/generator-components, 1.1.1 for @asyncapi/generator-helpers, and 6.11.2 for @asyncapi/specs.
Attribution is unverified. The OSV advisories reference Shai-Hulud source material from November 2025. Behavioral notes in the Amazon Inspector OSV entries describe obfuscated require-time spawning in the July 2026 versions, but no named actor or campaign has been confirmed for this wave.
A note on the compromised_at field#
The Attestd API response shows compromised_at: 2025-11-24 for all four packages. That reflects the OSV advisory publish date, which was written for the November 2025 Shai-Hulud incident and reused for the July 2026 re-compromise under the same advisory IDs. It is not evidence that the 2026 versions were a November 2025 event. The npm publish timestamps for 3.3.1, 0.7.1, 1.1.1, and 6.11.2 confirm July 14, 2026 as the actual re-compromise date.
This is a known limitation of OSV-id reuse and worth being explicit about in any automated pipeline consuming the compromised_at field.
What Attestd returns#
curl "https://api.attestd.io/v1/check?product=%40asyncapi%2Fgenerator&version=3.3.1" \
-H "Authorization: Bearer $ATTESTD_API_KEY"
{
"product": "@asyncapi/generator",
"version": "3.3.1",
"supported": true,
"risk_state": "critical",
"risk_factors": ["supply_chain_compromised"],
"confidence": 0.95,
"cve_ids": [],
"supply_chain": {
"compromised": true,
"sources": ["agent", "osv"],
"malware_type": "malware",
"description": "Malicious code in @asyncapi/generator (npm)",
"compromised_at": "2025-11-24T11:48:04Z"
},
"supply_chain_monitored": true
}
risk_state: critical driven entirely by supply_chain_compromised. No CVEs, no vulnerability record. A system checking only CVE state passes this version clean.
sources: ["agent", "osv"] on three of the four packages means the pipeline flagged these in real time, not only after OSV published an advisory. @asyncapi/specs shows sources: ["osv"] only, reflecting the different detection path for that package.
The clean current versions for all four:
| Package | Compromised | Clean |
|---|---|---|
| @asyncapi/generator | 3.3.1 | 3.3.0 |
| @asyncapi/generator-components | 0.7.1 | 1.0.0 |
| @asyncapi/generator-helpers | 1.1.1 | 1.1.0 |
| @asyncapi/specs | 6.11.2 | 6.11.1 |
All clean versions return risk_state: none with supply_chain.compromised: false.
Why re-compromise matters as a pattern#
The November 2025 Shai-Hulud wave hit over 500 npm packages. The assumption after a wave like that is that the affected packages are remediated, the advisories are published, and defenders move on. The July 14 event suggests a different model: packages that were already compromised once remain targets, either because the same actor retains access or because a different actor uses the prior compromise as a blueprint.
A pipeline that only checks whether a package was affected by a named historical campaign would have passed the July 2026 versions of these packages as clean. The compromised_at timestamps reference November 2025. The new malicious versions are distinct publishes with distinct npm metadata. The detection signal for the re-compromise is the supply chain monitoring layer catching the new versions as they appeared, not a lookup against the November 2025 advisory list.
If the re-compromise pattern repeats, the implication for any security layer that treats historical supply chain events as closed incidents is that it is operating on a stale threat model.
Coverage#
All four packages are covered. The compromised versions return risk_state: critical with supply_chain.compromised: true. The clean current versions return risk_state: none with supply_chain.compromised: false. Responses above are live from the production API as of July 15, 2026.
The related package @asyncapi/generator-react-sdk (OSV MAL-2025-190637, compromised versions 1.1.5 and 1.1.4 from November 2025) is also covered and is being reviewed for July 2026 re-compromise versions.
API documentation: attestd.io/docs. Detection ledger: github.com/attestd-io/detection-ledger. Machine speed thesis: attestd.io/thesis.