forge-jsx / forge-jsxy npm RAT: Campaign Continues into July 2026 with New Accounts

Five npm packages carrying a full cross-platform Remote Access Trojan are live on the registry right now. The forge-jsx campaign has been cycling through account rotations and npm takedowns since April 2026. We caught the July 2026 wave, confirmed a live C2 connection in our behavioral sandbox, and extracted the embedded C2 configuration from all nine tarballs.


By Tropico Security Research Team
Published: 2026-07-06
Reading time: ~9 minutes
TLP:WHITE, free to redistribute with attribution


 

The forge-jsx / forge-jsxy campaign is a long-running npm supply-chain attack first publicly documented by SafeDep in April 2026. Every package uses the same fake description, “Node.js integration layer for Autodesk Forge,” to appear legitimate in search results. After each npm takedown, new packages have appeared under fresh account names carrying the same payload.

 

SafeDep’s published research covers the campaign through the June 2026 packages (forge-jsx4, pino-zod, zod-pino). The five packages we are reporting here are not in any prior write-up. They were still live on npm at time of publication. We filed an abuse report with npm before publishing this post.

 


Table of Contents

  1. Campaign History
  2. What We Found
  3. Dynamic Confirmation
  4. Static Payload Analysis
  5. Account Attribution
  6. Full Capability Set
  7. How We Found This
  8. Honeytokens as a Detection Layer
  9. Indicators of Compromise
  10. Remediation

 


Campaign History

The packages below share a version counter that, across all documented waves, has not reset across renames or account changes. This is consistent with the same build pipeline publishing across all waves, though gaps in documentation exist and attribution to a single individual cannot be confirmed from package metadata alone.

 

Package name Versions Date Account Source
forge-jsx 1.0.0-1.0.66 Apr 7-May 3, 2026 johnceballos0716 SafeDep
forge-jsxy 1.0.66-1.0.91 May 4-26, 2026 jacksonkaandorp2 ([email protected]) SafeDep
forge-jsx4 1.0.122-1.0.123 Jun 21-22, 2026 rafael_silva SafeDep
pino-zod, zod-pino 1.0.121-1.0.125 Jun 22-23, 2026 (taken down) SafeDep
compose-logger-stand 1.0.126 Jul 2, 2026 jacksondkeindlson Tropico Security
zod-pino434 1.0.127-1.0.128 Jul 4-5, 2026 donimique Tropico Security
zod-pino444 1.0.128-1.0.131 Jul 5, 2026 donimique Tropico Security
zredis-typed 1.0.127 Jul 5, 2026 donimique Tropico Security, C2 confirmed
pinokio-redis 1.0.127 Jul 6, 2026 donimique Tropico Security

 

Campaign history prior to compose-logger-stand is from SafeDep’s published research (see References). The July 2026 entries are Tropico Security’s own findings.

 


What We Found

At Tropico Security, we build deception technology that detects attackers before they reach production systems. As part of our ongoing research into supply chain attacks through package registries, we identified five new package names carrying the same RAT payload, all still live on npm with no prior public reporting at time of detection.

 

Package Version(s) Account Email First seen (UTC)
compose-logger-stand 1.0.126 jacksondkeindlson [email protected] 2026-07-02 07:17
zod-pino434 1.0.127, 1.0.128 donimique [email protected] 2026-07-04 18:03
zod-pino444 1.0.128-1.0.131 donimique [email protected] 2026-07-05 04:38
zredis-typed 1.0.127 donimique [email protected] 2026-07-05 18:09
pinokio-redis 1.0.127 donimique [email protected] 2026-07-06 05:48

 

All five packages were still live on npm at time of publication (2026-07-06).

 


Dynamic Confirmation

[email protected] was detonated in our isolated sandbox on 2026-07-05. At npm install time, we observed:

 

  • TCP connection to 212.193.3.61:8765 (HTTP C2 API)
  • TCP connection to 212.193.3.61:9877 (WebSocket C2 relay)
  • Persistence written: /root/.config/autostart/forge-js-worker.desktop
  • Durable hidden runtime directory created: /root/.local/share/cfgmgr/.forge-jsxy/

 

🔍 Key Finding

212.193.3.61 is the secondary C2 server documented by SafeDep for this campaign. The other four packages tripped our static dropper signature but did not beacon during the sandbox window. This is consistent with the campaign’s CI-evasion logic built into the dropper: it explicitly checks for CI=true, GitHub Actions, GitLab CI, Travis, CircleCI, Jenkins, and TeamCity, and exits silently when any of these are detected. This design allows the packages to pass through many automated scanning environments while still executing on a developer’s local machine.

 


Static Payload Analysis

We statically unpacked all nine July tarballs (untar and read text files only, no code executed on the host) and computed per-file SHA-256 hashes across all packages.

 

Payload Comparison

  • 195 of 208 files are byte-for-byte identical across all eight donimique tarballs. The 13 differing files are package.json, name-embedding scripts, and the encrypted C2 slot. Every core capability module is identical across the eight packages.
  • 167 of 208 files are byte-identical between compose-logger-stand (jacksondkeindlson) and the donimique packages. This includes core capability modules: chromiumExtensionDbHarvest.js, keyboardTranslate.js, hfUpload.js, clipboardEventWatcher.js, solanaKeypair.js, postinstall-bootstrap.mjs.

 

The differing files in every case are exclusively identity and configuration: package name, version, and the encrypted C2 configuration slot. All capability modules are byte-identical across both accounts.

 

Dropper Behavior

The install-time dropper is at scripts/postinstall-agent.mjs, the final step in a five-stage postinstall chain. Based on static analysis of the source:

 

  1. CI environment check: Exits cleanly on CI=true, GITHUB_ACTIONS, GITLAB_CI, TRAVIS, CIRCLECI, JENKINS_URL, TEAMCITY_VERSION.
  2. Durable copy before execution: Copies itself to ~/.local/share/cfgmgr/.forge-jsxy/runtime/ before spawning the agent, so the RAT persists after npm uninstall.
  3. Detached background process: Forks with stdio: ignore, invisible to npm output.
  4. C2 IP not in process arguments: The source code contains a comment explicitly noting this is to keep the IP address out of ps aux and Task Manager process listings.
  5. OS autostart persistence: Registers on Linux, macOS, and Windows at install time.

 

C2 Configuration Recovery

The runtime C2 host is not stored in plaintext in the package. It is AES-256-GCM encrypted in dist/deploymentCipherData.js, with the decryption key stored as two XOR-obfuscated 16-byte halves embedded in the same file. We reconstructed the key halves and decrypted all nine blobs. The GCM authentication tag verified successfully for every package:

 

# donimique account, all 8 packages (GCM authentication tag verified)
{"publicHost":"212.193.3.61","relayPort":9877,"apiPort":8765,"defaultExplorerPassword":"secret"}

# jacksondkeindlson account, compose-logger-stand (GCM authentication tag verified)
{"publicHost":"204.10.194.247","relayPort":9877,"apiPort":8765,"defaultExplorerPassword":"secret"}

 

Both IPs and the session password match SafeDep’s documented campaign infrastructure. No additional C2 endpoints were found in the July payloads.

 


Account Attribution

Account Email Connection to prior campaign
jacksondkeindlson [email protected] Email address increments [email protected], the documented forge-jsxy maintainer per SafeDep. Same pattern, next number.
donimique [email protected] New account. Payload and C2 infrastructure match the documented campaign.

 

🔍 Key Finding

Across all documented packages, the version counter runs from 1.0.0 (forge-jsx, April 2026, per SafeDep) through 1.0.131 (zod-pino444, July 5, 2026, verified by us), with no reset observed across the account changes and package renames that are documented. The incrementing email pattern on jacksondkeindlson and the byte-identical payload across both new accounts are consistent with the same campaign continuing under new registrations, though we cannot confirm individual identity from package data alone.

 


Full Capability Set

Core capability modules are byte-identical to the SafeDep-documented forge-jsx payload. The list below is derived from static analysis of the compiled dist/ files in the July tarballs combined with SafeDep’s prior behavioral research. Each item is attributed accordingly.

 

  • Keylogger via uiohook-napi (confirmed by dependency + static analysis)
  • Clipboard monitor, 400ms poll via @napi-rs/clipboard and clipboard-event (confirmed by static analysis of clipboardEventWatcher.js)
  • Recursive .env file scanner, 13 filename variants (confirmed by static analysis)
  • Secrets file scanner targeting .solana, .ethereum, .bitcoin directories; UTC--* Ethereum keystores; *.seed, *.mnemonic, *.phrase; *.p12, *.pfx, *.jks (confirmed from assets/secret_filename_patterns.json)
  • Shell history theft for bash, zsh, fish, PSReadLine (confirmed by static analysis)
  • Crypto-wallet theft, BIP39 seed phrases, Solana Ed25519 keypairs, secp256k1 private keys via @scure/bip39 and tweetnacl (confirmed by dependency + static analysis of solanaKeypair.js)
  • Chromium and Electron browser extension database harvest across 21+ browser profiles (SafeDep behavioral research, confirmed by presence of chromiumExtensionDbHarvest.js)
  • Remote-filesystem WebSocket backdoor with full read/write (confirmed by presence of fsProtocol.js in dist/)
  • Desktop screenshots exfiltrated to Discord webhooks via jimp (SafeDep behavioral research, confirmed by dependency)
  • Exfiltration to HuggingFace Hub private repositories via @huggingface/hub (confirmed by dependency + static analysis of hfUpload.js)
  • WebRTC P2P relay via node-datachannel (confirmed by dependency)
  • Host inventory collection (SafeDep behavioral research)
  • Auto-upgrade with 6-hour cooldown (confirmed by static analysis of postinstall-agent.mjs)

 


How We Found This

Tropico Security conducts ongoing research into supply chain attacks through package registries. This investigation started with static analysis of suspected packages, followed by detonating [email protected] in an isolated behavioral sandbox to confirm the live C2 connection. All other packages were analyzed through static unpacking and file-level comparison only, with no code executed on the host.

 

Why Standard Tooling Misses This

This campaign is specifically designed to evade CI/CD pipeline scanners. The dropper exits silently in seven CI environments. Standard dependency scanning tools that run in CI will not catch it on a developer’s machine where none of those environment variables are set.

 

The most practical secondary detection layer for this specific RAT is a honeytoken planted in a developer’s .env file or credential store. This RAT scans for and exfiltrates .env files recursively. If a Tropico honeytoken is among those files, you receive an alert the moment the operator attempts to use the stolen token, regardless of whether the install-time dropper was ever caught.

 

Learn more about Tropico’s deception platform and honeytokens: tropicosecurity.com

 


Honeytokens as a Detection Layer

A honeytoken is a credential that is valid in format and indistinguishable from a real one, but is not authorized for any actual system. It is planted in locations an attacker would target. Because there is no legitimate reason for it to ever be used, any access attempt is an unambiguous indicator of compromise and triggers an immediate alert.

 

This RAT recursively scans developer machines for .env files and credential stores, exfiltrating everything it finds without filtering. A honeytoken planted in a .env file is stolen alongside the real credentials. The moment the attacker attempts to use it, the alert fires. This detection path requires no endpoint monitoring, no network visibility, and no prior awareness that the malicious package was ever installed.

 

At Tropico Security we build honeytokens designed for exactly this kind of deployment.

 


Indicators of Compromise

Network

Host Role
212.193.3.61 C2 server: HTTP :8765, WebSocket :9877, session password “secret”
204.10.194.247 C2 server: HTTP :8765, WebSocket :9877 (AS206216 Advin Services LLC, Nurnberg DE)
taohunter.ai Cover domain associated with C2 operator per SafeDep attribution

 

npm Accounts

Account Email
donimique [email protected]
jacksondkeindlson [email protected]

 

File System (written at install time)

OS Path
Linux ~/.local/share/cfgmgr/.forge-jsxy/ (durable hidden runtime, key artifact)
Linux ~/.config/autostart/forge-js-worker.desktop
Linux ~/.config/systemd/user/forge-js-worker.service
Linux / macOS ~/.local/share/.forge-js/postinstall-agent.log
macOS ~/Library/LaunchAgents/com.forgejs.worker.plist
Windows Task Scheduler: ForgeJSWorker
Windows HKCU\Software\Microsoft\Windows\CurrentVersion\Run: ForgeJSWorker

 

Tarball SHA-256 (computed by Tropico Security, 2026-07-06)

Package SHA-256
[email protected] 0085d5b5d4a2bbb3fd1f38e6b251872d4f753aa8f1ac7f20524c521ff5ca5933
[email protected] a99be9fe0e7d66064a11ee096fd8c1a9178e3ee2b761fa8a2bde81bfe846b9a2
[email protected] 9e570641fd815e2fd6cf50aaa847c43c2fe938c7b368bf7c239f511827ff9a24
[email protected] 93817e263f285f20ed213eb07bbab2857493183c0abf9563facfc65fdd4467f7
[email protected] b824500b6639443696cd7897b7d3bf61b8534441ac273d9f37edf84542681d07
[email protected] a5c8c01ecf3361e87390cf591c09d1857ea03d26f474429a5da88d0a72f10eaa
[email protected] 1d4ef70d7856704b373579ae23cba0ebf690ef062b29361f6aa0f51a1cdd9052
[email protected] a1853a45bcb561f96e0e7c0dec7f96e640ae53be56e65158880812ff104c9e41
[email protected] a400b0342add77fd3a58e086334b35e11d79e234b180bb360f48adcd61ec4acd

 


Remediation

If you installed any package with the description “Node.js integration layer for Autodesk Forge” that is not from the official Autodesk APS SDK, or any of the specific package names listed above:

 

  1. Check for the persistence artifact: run ls ~/.local/share/cfgmgr/.forge-jsxy/ on Linux or macOS. If this directory exists, the RAT has written a durable copy that survives package deletion and is likely still running.
  2. Find the running agent: look for a node process with a path pointing to .forge-jsxy/runtime/.
  3. Remove persistence: delete ~/.local/share/cfgmgr/.forge-jsxy/; remove forge-js-worker.desktop on Linux, com.forgejs.worker.plist on macOS, or the ForgeJSWorker Task Scheduler entry on Windows; disable the systemd user service if present.
  4. Rotate all secrets: treat every credential, SSH key, API token, .env file, and crypto wallet seed on the affected machine as compromised.
  5. Block C2 IPs at your perimeter: 212.193.3.61 and 204.10.194.247.

 

For a detection layer that works independently of whether the install was ever caught, see the Honeytokens as a Detection Layer section above.

 


Published by Tropico Security Research Team | tropicosecurity.com


References

  1. SafeDep, forge-jsx RAT analysis: https://safedep.io/malicious-forge-jsx-npm-rat/
  2. SafeDep, forge-jsxy evolution: https://safedep.io/malicious-forge-jsxy-npm-rat-evolution/

Share this :

Latest blog & articles

Adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Enim minim veniam quis nostrud exercitation