Open Source · · 2 days

IronWorm backdoored Arweave ecosystem npm packages

JFrog found a Rust-built npm worm in 36 packages published from the compromised asteroiddao account, carrying an eBPF kernel rootkit and a Tor C2. It backdated commits across nine GitHub organizations and republished via npm trusted publishing.

JFrog Security Research disclosed in early June 2026 that a self-propagating worm it named IronWorm had backdoored 36 npm packages, most of them in the Arweave and WeaveDB ecosystem, after compromising the asteroiddao publishing account. Unlike the JavaScript droppers that dominated npm attacks that year, IronWorm was a native Rust implant with a kernel-level rootkit.

The delivery was conventional enough. A preinstall hook executed a 976 KB Linux ELF binary before dependency resolution finished. Everything after that was not. The binary was packed with a modified UPX stub carrying altered magic values, which defeats signature-based unpackers, and every internal string was encrypted with a key unique to its call site, so recovering one string does not help with the next. Bundled with it was an eBPF program that hid the malware's processes and network connections from the kernel's own accounting, and a Tor client that wrapped plain HTTP command-and-control traffic in an onion circuit.

The collector targeted 86 environment variables and more than 20 credential file paths across AWS, GCP, Azure, Kubernetes, Docker, npm, and GitHub, together with a sweep for 2026-era AI provider keys covering Anthropic, OpenAI, Google Gemini, Cohere, Mistral, Groq, and xAI. Separate modules went after cryptocurrency wallets. JFrog noted that the operator had hardcoded his own wallet recovery phrase into the malware's skip list so that it would not rob him, which is how researchers came to have it.

Propagation ran two ways. The worm committed binaries into victims' GitHub repositories as build hooks, attributing the commits to "claude" so they read as AI tooling output, and it replaced GitHub Actions workflows with versions that exfiltrated ${{ toJSON(secrets) }}, attributing those to bot identities such as dependabot. It then abused npm's trusted publishing through OIDC to release poisoned versions under the compromised developers' names. JFrog counted 57 backdated commits across nine compromised GitHub organizations and said it could not match the implant, the rootkit, or the C2 tooling to any known family, indicating a custom-built operation.

Notes

  • JFrog enumerated 37 packages with one malicious version each, published from the compromised asteroiddao account and from other maintainer accounts reached through stolen credentials. Those coordinates are recorded on the artifacts here. The record previously carried a single artifact with a placeholder version and an all-zero SHA-256 standing in for unknown bytes; both are replaced.
  • Reported package counts vary between 36 and 37 depending on source and collection date. JFrog reported 57 backdated commits across nine compromised GitHub organizations, concentrated in the Arweave and WeaveDB ecosystem.
  • The implant is a 976 KB Rust ELF executed from a preinstall hook. Per-call-site string encryption means each string must be recovered individually, which slowed analysis.
  • JFrog found no match to any known infostealer, eBPF rootkit framework, or C2 toolkit, and assessed the operation as custom-built with dedicated infrastructure.
  • The operator's own cryptocurrency wallet recovery phrase was hardcoded into the malware's skip list so the wallet stealer would not target it.
  • OSSF malicious-package records preserve complete npm archive checksums for 31 of the releases. Together with four archives already recovered from npm, 35 of the 37 artifact records now have whole-file hashes. For wdb-core 0.1.2 and hbsig 0.3.2, Socket retained every member except the shared 976,568-byte install-deps ELF; precise partial reconstructions and their missing-member evidence are recorded in the samples manifest.

Appendix · Affected releases

0.1.1 no sample yet
  • OSSF MAL-2026-4720 maps these checksums to the complete weavedb-lite-0.1.1.tgz npm archive.
0.21.1 no sample yet
  • OSSF MAL-2026-4724 maps these checksums to the complete weavedb-sdk-base-0.21.1.tgz npm archive.
1.1.1 no sample yet
  • OSSF MAL-2026-4690 maps these checksums to the complete test-weavedb-sdk-1.1.1.tgz npm archive.
1.0.11 no sample yet
  • OSSF MAL-2026-4727 maps these checksums to the complete weavedb-warp-contracts-plugin-deploy-1.0.11.tgz npm archive.
0.0.2 no sample yet
  • OSSF MAL-2026-4483 maps these checksums to the complete arnext-arkb-0.0.2.tgz npm archive.
0.2.1 no sample yet
  • OSSF MAL-2026-4717 maps these checksums to the complete weavedb-console-0.2.1.tgz npm archive.
arnext npm
0.1.5 no sample yet
  • OSSF MAL-2026-4482 maps these checksums to the complete arnext-0.1.5.tgz npm archive.
roidjs npm
0.1.7 no sample yet
  • OSSF MAL-2026-4663 maps these checksums to the complete roidjs-0.1.7.tgz npm archive.
0.7.4 no sample yet
  • OSSF MAL-2026-4718 maps these checksums to the complete weavedb-exm-sdk-0.7.4.tgz npm archive.
0.0.10 no sample yet
  • OSSF MAL-2026-4538 maps these checksums to the complete create-arnext-app-0.0.10.tgz npm archive.
0.45.3 no sample yet
  • OSSF MAL-2026-4726 maps these checksums to the complete weavedb-tools-0.45.3.tgz npm archive.
wdb-core npm
0.1.2 sha256 cc2693ea…a284d3a1 download unavailable
0.3.1 no sample yet
  • OSSF MAL-2026-4545 maps these checksums to the complete cwao-tools-0.3.1.tgz npm archive.
test-ajs npm
0.1.19 no sample yet
  • OSSF MAL-2026-4689 maps these checksums to the complete test-ajs-0.1.19.tgz npm archive.
monade npm
0.0.7 no sample yet
  • OSSF MAL-2026-4613 maps these checksums to the complete monade-0.0.7.tgz npm archive.
0.7.4 no sample yet
  • OSSF MAL-2026-4719 maps these checksums to the complete weavedb-exm-sdk-web-0.7.4.tgz npm archive.
1.0.21 no sample yet
  • OSSF MAL-2026-4691 maps these checksums to the complete testnpmnmp-1.0.21.tgz npm archive.
3.0.1 no sample yet
  • OSSF MAL-2026-4712 maps these checksums to the complete warp-contracts-plugin-deploy-test-3.0.1.tgz npm archive.
wdb-cli npm
0.1.1 no sample yet
  • OSSF MAL-2026-4713 maps these checksums to the complete wdb-cli-0.1.1.tgz npm archive.
ai3 npm
0.3.5 no sample yet
  • OSSF MAL-2026-4476 maps these checksums to the complete ai3-0.3.5.tgz npm archive.
0.8.3 no sample yet
  • OSSF MAL-2026-4546 maps these checksums to the complete cwao-units-0.8.3.tgz npm archive.
0.5.3 no sample yet
  • OSSF MAL-2026-4486 maps these checksums to the complete atomic-notes-0.5.3.tgz npm archive.
cwao npm
0.5.6 no sample yet
  • The SHA-256 identifies the complete 0.5.6 tarball retained by the official npm registry; its bytes also match npm's signed SHA-512 integrity record.
  • OSSF MAL-2026-4544 maps the SHA-1 and SHA-512 checksums to the complete cwao-0.5.6.tgz npm archive.
0.45.3 no sample yet
  • OSSF MAL-2026-4716 maps these checksums to the complete weavedb-client-0.45.3.tgz npm archive.
wdb-sdk npm
0.1.2 no sample yet
  • OSSF MAL-2026-4714 maps these checksums to the complete wdb-sdk-0.1.2.tgz npm archive.
0.45.4 no sample yet
  • OSSF MAL-2026-4722 maps these checksums to the complete weavedb-offchain-0.45.4.tgz npm archive.
0.1.7 no sample yet
  • OSSF MAL-2026-4566 maps these checksums to the complete fpjson-lang-0.1.7.tgz npm archive.
0.45.2 no sample yet
  • OSSF MAL-2026-5192 maps these checksums to the complete weavedb-contracts-0.45.2.tgz npm archive.
0.45.3 no sample yet
  • OSSF MAL-2026-4721 maps these checksums to the complete weavedb-node-client-0.45.3.tgz npm archive.
arjson npm
0.1.4 no sample yet
  • The SHA-256 identifies the complete 0.1.4 tarball retained by the official npm registry; its bytes also match npm's signed SHA-512 integrity record.
  • OSSF MAL-2026-5189 maps the SHA-1 and SHA-512 checksums to the complete arjson-0.1.4.tgz npm archive.
hbsig npm
0.3.2 sha256 9330d0fb…9db72622 download unavailable
zkjson npm
0.8.5 no sample yet
  • The SHA-256 identifies the complete 0.8.5 tarball retained by the official npm registry; its bytes also match npm's signed SHA-512 integrity record.
  • OSSF MAL-2026-4739 maps the SHA-1 and SHA-512 checksums to the complete zkjson-0.8.5.tgz npm archive.
aonote npm
0.11.1 no sample yet
  • OSSF MAL-2026-4480 maps these checksums to the complete aonote-0.11.1.tgz npm archive.
0.45.3 no sample yet
  • OSSF MAL-2026-4715 maps these checksums to the complete weavedb-base-0.45.3.tgz npm archive.
0.45.3 no sample yet
  • OSSF MAL-2026-4725 maps these checksums to the complete weavedb-sdk-node-0.45.3.tgz npm archive.
wao npm
0.41.2 no sample yet
  • OSSF MAL-2026-4711 maps these checksums to the complete wao-0.41.2.tgz npm archive.
0.45.3 no sample yet
  • The SHA-256 identifies the complete 0.45.3 tarball retained by the official npm registry; its bytes also match npm's signed SHA-512 integrity record.
  • OSSF MAL-2026-4723 maps the SHA-1 and SHA-512 checksums to the complete weavedb-sdk-0.45.3.tgz npm archive.

Indicators

  • malware_familyIronWorm
  • commit_authorclaude
  • commit_authordependabot

References

  1. IronWorm: Shai-Hulud's rustier cousin - JFrog Security Researchresearch.jfrog.com
  2. IronWorm and New Miasma Worm Variant Hit npm in Supply Chain Attacks - The Hacker Newsthehackernews.com
  3. Rust-Written IronWorm Hits NPM Supply Chain - Dark Readingdarkreading.com
  4. IronWorm campaign - SafeDep Threat Intelligencesafedep.io
  5. OSSF malicious-packages databasegithub.com
  6. OSSF MAL-2026-4544 package-integrity record for cwao 0.5.6raw.githubusercontent.com
  7. OSSF MAL-2026-5189 package-integrity record for arjson 0.1.4raw.githubusercontent.com
  8. OSSF MAL-2026-4739 package-integrity record for zkjson 0.8.5raw.githubusercontent.com
  9. OSSF MAL-2026-4723 package-integrity record for weavedb-sdk 0.45.3raw.githubusercontent.com

Source record: oss/attacks/ironworm-npm/meta.yaml