@joyfill npm Packages Compromised: North Korea Blockchain C2 RAT

Two beta release packages in the @joyfill npm namespace were compromised yesterday evening. Both carry an import-time JavaScript implant delivering a remote access trojan. Both return risk_state: critical from Attestd as of this morning.
Socket has confirmed the campaign shares infrastructure and attribution with ViteVenom, the supply chain operation targeting the Vite frontend ecosystem that Attestd covered in July. Same threat cluster. Same blockchain-based command-and-control architecture. Same North Korean attribution. The campaign is iterating across new package namespaces rather than retreating.
What was compromised#
@joyfill/[email protected] and @joyfill/[email protected] both contain an import-time implant. Unlike most malicious npm packages that trigger through lifecycle hooks such as postinstall, this one executes the moment Node.js loads the CommonJS entry point. There is no install step to intercept. The malicious code runs when your application starts.
The implant uses a tiered blockchain resolver to retrieve its payload. It queries a hardcoded Tron address for a BSC transaction hash, decrypts the payload from that transaction, and executes it. If the Tron query fails, it falls back to an Aptos account. The payload can be rotated without publishing a new package version, which makes traditional hash-based detection insufficient.
A secondary detached Node.js process runs in parallel, reaching out to a hardcoded IP for a separate boot payload. This branch persists after a build, test, or CLI command exits. Removing the package does not guarantee the detached process has terminated.
The final payload is a full RAT with file upload, clipboard access, and credential harvesting from Git, GitHub CLI, GitHub Desktop, Visual Studio Code storage, and browser extension wallets. It deliberately avoids execution on machines with hostnames matching github-runner, buildbot, buildkitsandbox, and microsoft-standard-WSL2. The malware knows it is being watched and behaves accordingly in known analysis environments.
Stable releases of both packages are not confirmed affected. Only the specific beta and release candidate versions listed above are flagged.
What Attestd returns#
curl "https://api.attestd.io/v1/check?product=%40joyfill%2Flayouts&version=0.1.2-2773.beta.0" \
-H "Authorization: Bearer $ATTESTD_API_KEY"
{
"product": "@joyfill/layouts",
"version": "0.1.2-2773.beta.0",
"supported": true,
"risk_state": "critical",
"risk_factors": ["supply_chain_compromised"],
"actively_exploited": false,
"remote_exploitable": false,
"authentication_required": false,
"patch_available": false,
"fixed_version": null,
"confidence": 0.95,
"cve_ids": [],
"supply_chain": {
"compromised": true,
"sources": ["agent", "osv"],
"malware_type": "malware",
"description": "Malicious code in @joyfill/layouts (npm)",
"compromised_at": "2026-07-28T21:05:44Z",
"removed_at": null,
"source_published_at": "2026-07-28T21:05:44Z",
"observed_at": "2026-07-29T05:04:53Z",
"ingested_at": "2026-07-29T05:04:53Z",
"first_served_at": "2026-07-29T11:26:58Z"
},
"supply_chain_monitored": true
}
curl "https://api.attestd.io/v1/check?product=%40joyfill%2Fcomponents&version=4.0.0-rc24-2773-beta.4" \
-H "Authorization: Bearer $ATTESTD_API_KEY"
{
"product": "@joyfill/components",
"version": "4.0.0-rc24-2773-beta.4",
"supported": true,
"risk_state": "critical",
"risk_factors": ["supply_chain_compromised"],
"actively_exploited": false,
"remote_exploitable": false,
"authentication_required": false,
"patch_available": false,
"fixed_version": null,
"confidence": 0.95,
"cve_ids": [],
"supply_chain": {
"compromised": true,
"sources": ["agent", "osv"],
"malware_type": "malware",
"description": "Malicious code in @joyfill/components (npm)",
"compromised_at": "2026-07-28T21:04:30Z",
"removed_at": null,
"source_published_at": "2026-07-28T21:04:30Z",
"observed_at": "2026-07-29T05:04:52Z",
"ingested_at": "2026-07-29T05:04:52Z",
"first_served_at": "2026-07-29T11:27:14Z"
},
"supply_chain_monitored": true
}
patch_available: false and fixed_version: null are correct. The affected versions are beta and release candidate releases. There is no safe version to upgrade to within the compromised release lines.
The new timestamp fields visible in both responses show the detection timeline. The packages were published at approximately 21:04 and 21:05 UTC on July 28. The pipeline observed them at 05:04 UTC on July 29, roughly eight hours after publication. The API began serving the compromised signal at 11:26 UTC, approximately fourteen hours after the malicious versions appeared on the registry.
Why the blockchain C2 matters#
Most supply chain malware uses a static C2 address or a hardcoded payload. Take down the server, neutralize the threat. The blockchain approach changes this. The payload address lives in a transaction on Tron or Aptos. There is no server to take down. The operator can update the payload by publishing a new blockchain transaction. Packages already installed can be retasked without publishing a new npm version.
This is identical to the infrastructure ViteVenom used. Attestd flagged those packages in July. The same threat cluster has now moved to a different namespace and published again. The campaign is not a one-time operation. It is a sustained distribution capability.
What this looks like in an automated pipeline#
A developer or autonomous agent installs a joyfill beta dependency. There is no lifecycle hook to intercept. The package passes a standard install. On first import, the implant runs. By the time any human looks at logs, credentials are already in transit to an operator-controlled destination.
An automated pipeline calling Attestd before allowing package installation gets a different outcome. supply_chain.compromised: true is returned before any code executes. The decision to proceed or reject happens at the API response, not at runtime.
Remediation#
Check your package-lock.json, yarn.lock, or pnpm-lock.yaml for either of the following:
- @joyfill/layouts at version 0.1.2-2773.beta.0
- @joyfill/components at version 4.0.0-rc24-2773-beta.4 Also check node_modules directly. If either package was installed at any point, treat the environment as compromised regardless of whether you have since removed it. The detached process launched at import time may have survived the removal.
If you installed either version, remove both packages from lockfiles, caches, internal mirrors, build images, and deployment artifacts. Purge from every environment that ran an install, including CI build images, Docker layers, and any staging or production environments where a build artifact was deployed.
Rotate credentials that were accessible from the affected Node.js process. Based on the known payload capabilities:
- Git credentials and SSH keys
- GitHub CLI tokens and GitHub Desktop session tokens
- Credentials stored in Visual Studio Code
- Browser extension wallets on developer machines where the package was loaded
- Chromium and Firefox saved credentials on affected machines
- Any secrets in environment variables at the time the process ran Kill any detached Node.js processes that cannot be accounted for. Reboot affected machines if process lineage is unclear.
Treat pre-release versions as higher risk going forward. Beta and release candidate packages receive less automated scrutiny and are a consistent target vector for this campaign cluster. If your pipeline installs pre-release versions automatically, add a supply chain check before allowing installation.
Coverage#
@joyfill/[email protected] and @joyfill/[email protected] are covered and return risk_state: critical with supply_chain.compromised: true. Stable releases of both packages are not flagged. Responses above are live from the production API as of July 29, 2026.
Attribution: Socket confirmed North Korean attribution and infrastructure overlap with ViteVenom.
API documentation: attestd.io/docs. Detection ledger: github.com/attestd-io/detection-ledger. ViteVenom coverage: attestd.io/blog/vitevenom-vite-npm-blockchain-c2-rat.
Related
Data & InsightENCFORGE: the JADEPUFFER operator returns with AI-specific ransomware. The entry point never changed.
The JADEPUFFER operator deploys ENCFORGE, AI-specific ransomware targeting model weights and vector indexes. Attestd shows Langflow 1.9.1 still critical.
Robert7 min read
Data & InsightViteVenom: six npm packages targeting Vite developers use blockchain C2 to deliver a RAT
Six npm packages impersonating the @vitejs scope carry a RAT delivered via Tron, Aptos, and BSC blockchain C2. risk_state: critical, no CVE.
Robert4 min read
Data & Insightjscrambler 8.14.0 through 8.20.0: IronWorm infostealer and a self-propagating npm worm
Five jscrambler releases carried IronWorm, a Rust infostealer that steals credentials and spreads via stolen npm tokens. risk_state: critical, no CVE.
Robert5 min read