The npm Worm Era: What Shai-Hulud Started, Who’s Continuing It, and How Defenders Should Adapt

September 2025’s self-replicating npm worm rewrote the supply-chain threat model — bundle.js + TruffleHog harvesting secrets, victim-owned GitHub repos as exfil sinks, and stolen npm publish tokens turning every infected developer into a new release vehicle. Six months later, the playbook is the new normal.

Key Takeaways
  • What: Shai-Hulud is a self-replicating npm worm that scans developer and CI environments with TruffleHog, exfiltrates GitHub PATs / npm tokens / cloud keys to public GitHub repos on the victim’s own account, and uses the stolen npm publish tokens to trojanize further packages the victim owns.
  • Who is affected: Any organization that installs JavaScript / TypeScript packages from npm into developer workstations or CI/CD runners with ambient cloud and GitHub credentials — especially shops that allow lifecycle scripts during npm install.
  • Exploitation status: In the wild since the September 14–15, 2025 wave that began with @ctrl/tinycolor; 500+ packages ultimately compromised. The TeamPCP “mini Shai-Hulud” SAP campaign in April 2026 reuses the same exfil-to-victim-repo signature, confirming the playbook is generalizing.
  • Action this week: Run npm ci --ignore-scripts in CI, rotate every long-lived GitHub PAT and npm token any developer or runner has touched in the last 30 days, and audit your GitHub org for public repos named Shai-Hulud or matching the mini-Shai-Hulud description.
  • Action this quarter: Move to npm OIDC trusted publishing with workflow-scoped trust policies (not org-wide), enforce SBOM completeness as a release gate, and add behavioral detection on npm install → child-process spawn patterns.

Executive Summary

In September 2025, the npm registry experienced its first true worm campaign. The malware — dubbed “Shai-Hulud” after a string embedded in its payload (a reference to Frank Herbert’s Dune) — began with a single compromised package (@ctrl/tinycolor, ~2.2M weekly downloads at the time of compromise) and propagated automatically across the ecosystem, ultimately infecting more than 500 packages. The mechanism that distinguished it from prior npm supply-chain attacks was structural: the malware did not just steal credentials, it used the stolen npm publish tokens to push trojanized versions of other packages on which the victim had publish rights. Every infected developer or CI runner became a new release vehicle.

The September 2025 wave is, today, table stakes for how npm attacks work. CISA issued a public alert on September 23, 2025, characterizing it as a “widespread supply chain compromise impacting the npm ecosystem.” Palo Alto Unit 42’s npm threat-landscape analysis (most recently updated May 1, 2026) documents how the post-Shai-Hulud landscape has evolved: the worm pattern has been copied (the TeamPCP “mini Shai-Hulud” SAP @cap-js campaign in April 2026), the exfil-to-victim-GitHub-repo signature has generalized across campaigns, and OIDC trusted-publishing misconfigurations have become the new injection vector. For organizations that haven’t rebuilt their npm threat model since 2024, this article is a current-state snapshot of what defenders need to assume and what controls now matter.

Packages Trojanized
500+
Confirmed in the Shai-Hulud wave; growing as new victims’ tokens push further releases.
Patient-Zero Reach
~2.2M dl/wk
Weekly downloads of @ctrl/tinycolor at the moment it was first trojanized.
Exfil Channel
github.com
Public repos created on the victim’s own GitHub account — no external C2 to blocklist.

Technical Analysis

Root cause: lifecycle scripts as a trusted code-execution primitive

npm packages can declare preinstall, install, and postinstall scripts that execute arbitrary code during installation — a feature designed for legitimate build steps (native-binary compilation, platform-specific bootstrapping, asset generation). For an attacker who can publish a package to the registry, this feature is a trusted RCE primitive on every machine that installs the package. The Shai-Hulud worm exploits this property at the population level: not by social-engineering individual targets, but by infecting maintainers’ own machines, harvesting their npm publish tokens, and using those tokens to trojanize the next round of packages. Each infected developer becomes a new release vehicle, which is why the campaign quickly crossed the threshold from incident to worm.

Threat Actor Profile

Threat Actor Profile
Shai-Hulud cluster (original wave)
AliasesShai-Hulud (named after a Dune reference embedded in the payload); spinoff campaigns include “mini Shai-Hulud” (TeamPCP, SAP @cap-js, April 2026).
Assessed motivationFinancially motivated — harvested credentials are immediately monetizable (cloud spend abuse, account resale, follow-on intrusion) and the worm propagation pattern is consistent with maximizing harvested-token volume.
Active sinceSeptember 14–15, 2025 (initial wave); ongoing — spinoffs continuing through 2026.
Typical targetsMaintainers of widely-used npm packages (population-level harvesting); CI/CD runners with cloud and GitHub credentials; any organization that allows lifecycle scripts during install.
Signature TTPsEmbedded bundle.js payload that drops a TruffleHog binary, scans the host filesystem and environment for secrets, exfiltrates AES- or base64-encoded results to public GitHub repos on the victim’s own account, and self-propagates using stolen npm publish tokens.
This incident fits becauseThe TeamPCP “mini Shai-Hulud” campaign (April 2026) carries the identical exfil-repo description string and Bun-based stealer architecture — explicit pattern reuse, attributed by Wiz as a related cluster.

Attack-chain execution

The end-to-end chain from a single compromised maintainer to ecosystem-wide propagation has six observable phases:

Shai-Hulud Worm Execution Chain
Patient zero → population-level propagation
1. Initial maintainer compromiseA maintainer’s npm publish token is harvested — via phishing, prior credential leak, or an earlier round of trojanized installs against the maintainer’s own dev environment.
2. Trojanized releaseAttacker publishes a new patch version of one of the maintainer’s packages with a malicious bundle.js shipped in the tarball and a lifecycle script that executes it during npm install.
3. Secret harvest via TruffleHogbundle.js fetches and executes a TruffleHog binary that recursively scans the host filesystem and environment for GitHub PATs, npm tokens, AWS / GCP / Azure credentials, SSH keys, and dotfile-resident secrets.
4. Exfiltration to victim-owned GitHubUsing the stolen GitHub PAT, the malware creates a public repository on the victim’s own GitHub account named Shai-Hulud and pushes base64-encoded findings into it. (Some variants also POST to webhook.site URLs hardcoded in the payload.)
5. GitHub Actions persistenceMalicious workflow file (e.g. .github/workflows/shai-hulud-workflow.yml) is injected into the victim’s repos to re-trigger secret harvest on every Actions run — persistence that survives the npm package being unpublished.
6. Self-replication via npm publishWith the victim’s stolen npm publish token, the malware automatically trojanizes other packages on which the victim has publish rights — producing the worm property and the 500+ package fan-out.

The exfil-to-victim-repo signature is the deepest defensive failure

Traditional supply-chain malware exfiltrates to an attacker-controlled endpoint — a hardcoded C2 domain, an obscure DNS server, an attacker-owned S3 bucket. Defenders blocklist those endpoints; researchers sinkhole them; attribution flows from the C2 fabric. Shai-Hulud broke that model. The exfil sink is the victim’s own GitHub account. Outbound traffic to github.com from a developer workstation or CI runner is universally allowlisted; the API calls are authenticated with the victim’s own valid PAT; the resulting repository looks (until the contents are inspected) like any other personal project. There is nothing to blocklist, nothing to sinkhole, and nothing to attribute — only a description-string IOC (the literal name Shai-Hulud) to hunt for across thousands of developer accounts.

Affected package families (illustrative, not exhaustive)

The September 2025 wave compromised packages across multiple maintainer namespaces. The most consequential by download volume was the @ctrl/* family (a single maintainer’s portfolio of color utilities, torrent clients, Angular helpers, etc., all sharing publish credentials). Documented affected packages include:

  • @ctrl/tinycolor — the index case, ~2.2M weekly downloads at compromise.
  • @ctrl/deluge, @ctrl/qbittorrent, @ctrl/transmission, @ctrl/shared-torrent, @ctrl/torrent-file, @ctrl/magnet-link — torrent client libraries.
  • @ctrl/ngx-codemirror, @ctrl/ngx-csv, @ctrl/golang-template — Angular and templating helpers from the same namespace.
  • angulartics2, encounter, and dozens of unrelated packages whose maintainers were caught in subsequent rounds of credential harvest.

The full list is dynamic — published advisories from StepSecurity, Wiz, Aikido Security, Socket, and Snyk contain rolling enumerations as the post-incident triage continues. Treat any installation between approximately September 14, 2025 09:00 UTC and September 22, 2025 of a package from a known-affected namespace as scoped for compromise pending evidence to the contrary.


Impact Assessment

The Shai-Hulud blast radius is wider than the 500+ packages directly trojanized: every developer who ran npm install against one of the affected versions, on a workstation or CI runner that had ambient GitHub or cloud credentials, exported those credentials to an attacker-controlled bundle. CI runners are the worst-case host: they typically hold elevated cloud roles, signing keys, and write-tier repo PATs, and they run unattended. A single trojanized indirect dependency in a build chain — pulled in three levels deep by a transitive resolver — was enough to compromise the runner.

The follow-on impact is the part defenders should still be triaging today. Cloud credentials stolen in September 2025 may still be live in environments that didn’t rotate; GitHub Actions persistence workflows planted in the victim-repo phase keep re-harvesting on every workflow run; npm tokens that weren’t rotated are still capable of pushing further trojanized releases. The campaign’s “cleanup” is necessarily multi-month, not multi-day.

MITRE ATT&CK Mapping
Observed techniques in the Shai-Hulud campaign
TacticTechniqueHow it appears here
Initial AccessT1195.002 Supply Chain Compromise: Compromise Software Supply ChainTrojanized npm package releases delivered through the registry to every downstream installer.
ExecutionT1059.007 Command and Scripting Interpreter: JavaScriptThe bundle.js lifecycle-script payload executed under Node during npm install.
Credential AccessT1552.001 Unsecured Credentials: Credentials In FilesTruffleHog filesystem scan for dotfiles, CLI credential caches (~/.aws, ~/.config/gcloud, ~/.azure), and SSH keys.
PersistenceT1546 Event Triggered Execution (GitHub Actions variant)Injected .github/workflows/shai-hulud-workflow.yml re-runs credential harvest on every workflow trigger.
ExfiltrationT1567 Exfiltration Over Web ServiceEncoded findings pushed to public repos on the victim’s own GitHub account, named Shai-Hulud; some variants additionally POST to webhook.site URLs.
Lateral Movement / Resource DevelopmentT1098 Account ManipulationStolen npm publish tokens used to trojanize other packages the victim maintains — the worm step.
Collection / ImpactT1530 Data from Cloud StorageStolen AWS / GCP / Azure credentials enable subsequent cloud-data theft beyond the immediate developer-host footprint.
Parallel evidence from the Java ecosystem (NDSS 2025, JBomAudit): A study of 25,882 Java SBOMs found that 7,907 SBOMs failed to disclose direct dependencies and 4.97% of those omitted dependencies were vulnerable. The figure is Java-specific and is cited here only as parallel evidence that SBOM completeness is a systemic gap across modern package ecosystems — not an npm-specific statistic. The structural problem (transitive dependencies escaping inventory) applies to npm at least as severely; specific npm SBOM-coverage studies are still emerging.

Detection & Response

Shai-Hulud’s detection surface has four layers: the npm install event itself, the TruffleHog/secret-scan behavior on the host, the exfil-repo creation on GitHub, and the GitHub Actions persistence file. Defenders who instrument all four catch the chain; defenders who only watch one will miss most infections.

High-fidelity IOCs

  • GitHub repo description / name match (highest fidelity): A public repository named Shai-Hulud on a user account who didn’t create it intentionally. The TeamPCP spinoff uses the description string “A Mini Shai-Hulud has Appeared.”
  • Injected GitHub Actions workflow: The presence of .github/workflows/shai-hulud-workflow.yml (or any workflow that wasn’t committed by a known maintainer) in any repo owned by a developer or org.
  • npm lifecycle-script anomaly: bundle.js dropped on disk by a freshly-installed package, especially a package whose prior versions did not ship one.
  • TruffleHog binary execution from an npm install context: The TruffleHog binary appearing on a developer host or CI runner immediately after an npm install — particularly when it was not present before.
  • Outbound webhook.site traffic during npm install: hardcoded webhook URLs in some bundle.js variants.
  • Cleared / mismatched npm token usage: a token publishing packages outside its owner’s historical maintenance pattern.
Logging prerequisites: The GitHub IOCs require org-level audit log access (GitHub Enterprise Cloud or Enterprise Server) or, for individual accounts, a sweep via the GitHub API. The npm-install IOCs require endpoint EDR with command-line and process-creation logging. Without both, the highest-fidelity signals are invisible.

Illustrative Detection Rules

Rule 1 — GitHub repository creation signature. The deterministic Shai-Hulud (and mini-Shai-Hulud) detection: a freshly-created public repo on a developer account named Shai-Hulud or carrying the mini-Shai-Hulud description string.

title: Shai-Hulud Exfiltration Repo Created on Developer Account id: 8a7c1e9d-shaihulud-exfil-repo status: experimental description: > Detects creation of a public GitHub repository whose name or description matches the Shai-Hulud worm exfiltration signature. Originated September 2025; reused by the TeamPCP "mini Shai-Hulud" campaign in April 2026. logsource: product: github service: audit detection: selection: action: repo.create repo.visibility: public match_original: repo.name: 'Shai-Hulud' match_mini: repo.description|contains: 'A Mini Shai-Hulud has Appeared.' condition: selection and (match_original or match_mini) fields: - actor - repo.name - repo.description - created_at falsepositives: - Legitimate security-research repos that deliberately name themselves Shai-Hulud — rare; verify by owner. level: critical tags: - attack.t1567 - attack.exfiltration references: - https://www.cisa.gov/news-events/alerts/2025/09/23/widespread-supply-chain-compromise-impacting-npm-ecosystem

Rule 2 — npm install spawns secret-scanning child process. Catches the active-infection moment: node (or npm) executing a child process that looks like a credential scanner. Tuned with a baseline-by-package allowlist so legitimate lifecycle scripts (esbuild, sharp, node-gyp builds) don’t pollute the signal.

title: npm install spawns secret-scan child process (Shai-Hulud TTP) id: 1d4e2c5b-npm-secret-scan-spawn status: experimental description: > Detects an npm/yarn/pnpm install lifecycle script that spawns a child process resembling TruffleHog or another credential scanner. The Shai-Hulud worm uses this pattern to harvest GitHub PATs, npm tokens, and cloud keys from the host filesystem. logsource: product: linux service: process detection: parent: parent_process.name: - node - npm - yarn - pnpm scanner_child: process.name|contains: - trufflehog - gitleaks process.command_line|contains: - --json - filesystem - --no-update filter_known_good: # Allowlist of legitimate packages whose postinstall hooks read env or scan paths. parent_process.command_line|contains: - 'esbuild' - 'sharp' - 'node-gyp' condition: parent and scanner_child and not filter_known_good fields: - parent_process.command_line - process.command_line - process.working_directory - user.name falsepositives: - Developers running TruffleHog intentionally on a clean shell — the parent process will not be npm/node. level: high tags: - attack.t1059.007 - attack.t1552.001

Rule 3 — injected shai-hulud-workflow.yml in a Git repo. Catches the GitHub Actions persistence step.

title: Suspicious GitHub Actions Workflow Added (Shai-Hulud persistence) id: 92c0a3f7-shaihulud-actions-persist status: experimental description: > Detects a commit that adds a workflow named shai-hulud-workflow.yml or a similarly-named workflow file matching the worm's persistence step. logsource: product: github service: audit detection: selection: action: workflow.created_workflow_run workflow_match: workflow.path|contains: - 'shai-hulud' - '.github/workflows/shai-hulud' condition: selection and workflow_match fields: - repo - actor - workflow.path - created_at level: critical tags: - attack.t1546 - attack.persistence

Rule 4 — KQL hunting query: outbound webhook.site from a CI runner or developer host during npm install. Some bundle.js variants exfil to webhook.site URLs in addition to (or instead of) the GitHub repo channel.

// KQL hunt — outbound webhook.site during/after an npm install context DeviceNetworkEvents | where Timestamp > ago(30d) | where RemoteUrl has "webhook.site" | join kind=inner ( DeviceProcessEvents | where Timestamp > ago(30d) | where InitiatingProcessFileName in~ ("node.exe", "node", "npm.cmd", "npm", "pnpm.cmd", "pnpm", "yarn.cmd", "yarn") | project DeviceId, InitiatingProcessId, InitiatingProcessCommandLine, ProcessStartTime = Timestamp ) on DeviceId, InitiatingProcessId | where Timestamp between (ProcessStartTime .. (ProcessStartTime + 10m)) | project Timestamp, DeviceName, InitiatingProcessCommandLine, RemoteUrl, RemoteIP

Correlation guidance for the SOC analyst:

  • Rule 1 alone is high-confidence compromise — investigate the owner’s developer host, rotate every token associated with that GitHub identity, and treat all packages they maintain on npm as scoped for trojanization until proven otherwise.
  • Rule 2 followed within 10 minutes by Rule 1 on the same user’s GitHub is the kill-chain signature — the worm is actively running on the developer host and has just exfiltrated. Isolate the host, kill the running node process tree, and force-rotate npm credentials before the next package push.
  • Rule 3 alone may indicate dormant persistence even if the initial infection has been cleaned. Sweep all repos owned by potentially-compromised accounts.
  • Time-window matters. The original September 2025 wave concentrated infections in a roughly 48-hour window; spinoffs like TeamPCP’s mini Shai-Hulud in April 2026 had a 2-hour publish window. Correlate any of the rules above against the known campaign timestamps before assuming a routine alert.

Mitigation & Remediation

There is no “patch” for Shai-Hulud in the traditional sense — npm and Yarn are not broken; the registry was abused. Remediation is a combination of operational hygiene (token rotation, scope tightening, lockfile discipline) and behavioral controls (lifecycle-script policy, audit-log monitoring). The matrix below maps the canonical defender actions to urgency tiers so a SOC can sequence the work.

Defender Quick-Reference Matrix
Sequenced actions for npm supply-chain hygiene post-Shai-Hulud
ActionScopeUrgency
Audit GitHub org for Shai-Hulud repos & mini-Shai-Hulud description stringEvery member account + service identityToday
Rotate every long-lived GitHub PAT and npm token used by devs / runnersAll tokens issued before today, especially those used on hosts that ran npm install Sept 2025 onwardToday
Run npm ci --ignore-scripts in CI by defaultAll build pipelines; explicit allowlist for packages whose scripts you trustThis week
Pin lockfiles with integrity hashes; reject floating ranges in package.jsonAll repos; CI fails if lockfile drift is detectedThis week
Migrate to npm OIDC trusted publishing with workflow-scoped trust policyEliminate long-lived publish tokens; restrict policy to canonical release workflow on protected branch onlyThis month
Sweep all developer repos for injected shai-hulud-workflow.ymlEvery repo on potentially-compromised accountsThis week
SBOM completeness as a release gateEvery release CI: fail if transitive deps absent from inventoryThis quarter
Behavioral EDR on dev/CI hosts: alert on npm install → spawn-of-secret-scannerEvery machine that executes lifecycle scriptsThis quarter
  1. Hunt before you harden. Audit every GitHub org and developer account for the Shai-Hulud repo signature and for the mini-Shai-Hulud description string. Any match means you already have a compromise — rotate first, harden second.
  2. Rotate aggressively, not selectively. Don’t try to identify which credentials were exfiltrated. Assume every long-lived token on every machine that has run npm install in the last 30 days is compromised, and rotate uniformly.
  3. Disable install scripts in CI by default. Use npm ci --ignore-scripts (or NPM_CONFIG_IGNORE_SCRIPTS=true) and maintain an explicit allowlist of packages that legitimately need lifecycle scripts to build. This is the single highest-leverage control change.
  4. Pin everything, hash-verify everything. Use lockfiles with integrity hashes. Reject floating semver ranges in package.json for production builds.
  5. Move to OIDC publishing with workflow-scoped trust. Eliminate long-lived npm publish tokens; the TeamPCP campaign showed that overly-broad OIDC trust policy is the new injection vector, so scope trust to one workflow on one protected branch.
  6. Sweep for the GitHub Actions persistence file. Check every repo on every potentially-affected account for .github/workflows/shai-hulud-workflow.yml (or any other workflow file that wasn’t committed by a known maintainer).
  7. Instrument the secret-scan behavior. Behavioral EDR rules that alert when node/npm spawns a child process resembling TruffleHog (Rule 2) catch the worm during execution — before the exfil step completes.
  8. Make SBOMs a release gate, not a release artifact. Fail the release pipeline if any transitive dependency is absent from the SBOM. SBOM completeness gaps are how omitted-but-vulnerable packages slip through.

Strategic Context

For two decades, defenders treated npm as a developer-productivity dependency: a thing that exists, that you patch when it has a CVE, that you don’t expose to the internet. Shai-Hulud forced a different framing. The registry itself is now an authenticated, attacker-reachable command-and-control fabric. A maintainer’s laptop is a foothold from which trojanized releases can reach millions of downstream installers in hours. A CI runner is a credential vault where every install operation is implicitly trusted code execution. There is no version of npm that fixes this; there are only operational practices that constrain it.

The TeamPCP “mini Shai-Hulud” campaign in April 2026 made the generalization explicit: the original wave’s tradecraft — secret-scan-with-TruffleHog, exfil-to-victim-owned-GitHub, self-propagate-via-stolen-publish-tokens — is now a playbook other actors are running, against other ecosystems and other supply chains. Defenders who built their npm threat model in 2024 are reasoning about a fundamentally different attack surface than the one they have today.

Karma-X Perspective

The dev host is the new endpoint — and behavior, not signature, is the only viable defense

Every static control that worked against pre-2025 npm threats fails against Shai-Hulud. There is no malicious IP to blocklist (exfil is to github.com). There is no malicious hash to ban (every bundle.js is freshly minified per release). There is no malicious package list to deny (the trojanized version inherits the legitimate package name). SBOM scanners report “package present, version pinned, no known CVE” while the worm is actively harvesting secrets.

What works is behavioral protection at the developer and CI endpoint: monitoring the process-spawn tree, the file-write pattern, the outbound-network pattern, and the GitHub audit log for the specific behavioral signatures the worm produces — npm install spawning TruffleHog, fresh shai-hulud-workflow.yml commits, a brand-new public repo named Shai-Hulud on a developer account. Karma-X is built around exactly this thesis: behavioral detection at machine speed on the systems that traditionally have no agent and where every install operation is trusted code execution.


Related Karma-X Coverage

  • TeamPCP / “mini Shai-Hulud” SAP @cap-js campaign (April 2026). Direct lineage: the spinoff that adopted the original wave’s exfil-to-victim-repo signature and added an npm-OIDC-trusted-publishing misconfiguration vector. Read the Karma-X analysis.
  • Cisco Catalyst SD-WAN (UAT-8616) firmware-downgrade-and-restore persistence (May 2026). Different vector, same architecture: persistent attacker presence in the management plane via behavioral controls that traditional FIM is blind to. Read the Karma-X analysis.
  • Frontier AI & the supply-chain attack family (Q1 2026 wave). LiteLLM, Axios, CPU-Z, ChatGPT sandbox — the broader Q1 2026 supply-chain incident pattern that culminates in Shai-Hulud-class worms. Read the Karma-X analysis.

Timeline

2025-09-14
Patient zero: @ctrl/tinycolor. Trojanized version published to npm; bundle.js + TruffleHog payload begins secret harvest on every install.
2025-09-15–22
Worm propagation. Stolen npm tokens used to trojanize ~500 additional packages across multiple maintainer namespaces (@ctrl/*, angulartics2, rxnt-*, and others). Public “Shai-Hulud” repos begin appearing on victim accounts.
2025-09-15–16
First researcher write-ups. StepSecurity, Wiz, Aikido Security, Socket, and Snyk publish coordinated analyses identifying the worm pattern, the bundle.js payload, and the GitHub-repo exfil signature.
2025-09-23
CISA alert. “Widespread Supply Chain Compromise Impacting npm Ecosystem” published with defender guidance.
2026-04-29
TeamPCP “mini Shai-Hulud” spinoff. SAP @cap-js and mbt packages compromised via an over-broad npm OIDC trusted-publishing policy; exfil to victim-owned GitHub repos with the description string “A Mini Shai-Hulud has Appeared.” Over 1,100 victim repos created.
2026-05-01
Unit 42 updated npm threat landscape. Palo Alto Networks publishes the May 2026 refresh of the post-Shai-Hulud npm threat surface; characterizes the worm pattern as “the new normal” and details the OIDC-misconfiguration vector behind the TeamPCP follow-on.

Sources & References

  1. Palo Alto Networks Unit 42. The npm Threat Landscape: Attack Surface and Mitigations (Updated May 1, 2026). Link
  2. CISA. Widespread Supply Chain Compromise Impacting npm Ecosystem (September 23, 2025). Link
  3. Titan Layer. The npm Threat Landscape: Attack Surface and Mitigations. Link
  4. NDSS 2025. JBomAudit: Assessing the Landscape, Compliance, and Security Implications of Java SBOMs (cited as parallel evidence; Java-ecosystem study). Link
  5. StepSecurity, Wiz, Aikido Security, Socket, and Snyk — coordinated September 2025 disclosures of the Shai-Hulud worm. Linked from the Unit 42 and CISA references above.

Sources

  1. The npm Threat Landscape: Attack Surface and Mitigations (Updated May 1)
  2. NDSS 2025 – JBomAudit: Assessing The Landscape, Compliance,
  3. The npm Threat Landscape: Attack Surface and Mitigations
  4. Widespread Supply Chain Compromise Impacting npm Ecosystem