SOC Prime Bias: Critical

30 Jul 2026 15:32 UTC

DEV#POPPER RAT Delivered Through Compromised Joyfill npm Releases

Author Photo
SOC Prime Team linkedin icon Follow
DEV#POPPER RAT Delivered Through Compromised Joyfill npm Releases
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

Summary

Two compromised beta releases of the @joyfill npm package were found containing an import-time JavaScript implant. The implant uses blockchain transactions across Tron, Aptos, and BNB Smart Chain to resolve and download the DEV#POPPER remote access trojan (RAT). The campaign targets developer workstations and CI/CD pipelines by executing malicious code as soon as the affected module is imported.

Investigation

The Socket Research Team uncovered the compromise while analyzing beta versions of @joyfill/layouts and @joyfill/components. Researchers identified a multi-stage payload delivery chain that combined obfuscated JavaScript with blockchain-backed dispatch mechanisms. The investigation linked the initial loader to the PolinRider family and confirmed that the final payload belonged to the DEV#POPPER malware family.

Mitigation

Developers should immediately remove the affected @joyfill beta versions from lockfiles, package caches, build environments, and deployment artifacts. Pinning dependencies to verified releases such as @joyfill/layouts@0.1.1 or @joyfill/components@4.0.0-rc24 is recommended. Security teams should also block the compromised versions through registry proxies and dependency governance tools.

Response

Any system that imported the affected packages should be isolated, and all credentials accessible to the compromised Node.js process should be rotated. Investigators should inspect developer applications, including VS Code, GitHub Desktop, and Discord, for unexpected changes to core modules. Endpoint and CI/CD telemetry should also be reviewed for detached Node.js processes, known C2 addresses, and suspicious blockchain RPC traffic.

Attack Flow

Simulation Execution

Prerequisite: The Telemetry & Baseline Pre-flight Check must have passed.

Rationale: This section details the precise execution of the adversary technique (TTP) designed to trigger the detection rule. The commands and narrative MUST directly reflect the TTPs identified and aim to generate the exact telemetry expected by the detection logic. Abstract or unrelated examples will lead to misdiagnosis.

  • Attack Narrative & Commands: The adversary has successfully injected malicious code into a widely used npm dependency (Supply Chain Compromise). When a developer runs npm install or starts a project, the malicious script executes. The script first attempts to hide its intent by assigning the require function to a global variable (global.r = require), allowing it to load modules anywhere in the application without calling require directly (obfuscation). Finally, it uses child_process.spawn to launch a detached shell process that connects back to a Command & Control (C2) server, attempting to evade detection by decoupling the malicious process from the parent Node.js process.

  • Regression Test Script:

    #!/bin/bash
    # Simulation script to trigger the Node.js injection detection rule.
    # This script creates a temporary malicious JS file and executes it via Node.js.
    
    MALICIOUS_FILE="malicious_pkg.js"
    
    echo "[+] Creating malicious Node.js script..."
    cat << 'EOF' > $MALICIOUS_FILE
    // Simulate global module injection (T1027)
    global.r = require;
    
    // Simulate detached process execution via child_process.spawn (T1059.006)
    const cp = require('child_process');
    cp.spawn('bash', ['-c', 'sleep 30 &'], { detached: true, stdio: 'ignore' });
    console.log("[!] Malicious payload executed.");
    EOF
    
    echo "[+] Executing malicious script via Node.js..."
    node $MALICIOUS_FILE
    
    echo "[+] Simulation complete. Check SIEM for Alert: Detection of Node.js Module Injection and Detached Process Execution."
  • Cleanup Commands:

    # Remove the simulated malicious file
    rm -f malicious_pkg.js
    # Kill any orphaned sleep processes spawned by the simulation
    pkill -f "sleep 30"