Skip to content
RESEARCH INDEX BREACHROAD / INTELLIGENCE NOTE

Joyfill npm packages ran a RAT when imported

Two Joyfill prereleases contained a RAT loaded on module import. We explain the blockchain C2 resolver, exposure evidence and response plan.

PUBLIC RESEARCH
AUTHOR
/ CEO of Breachroad · OSCP · PNPT
PUBLISHED
29 July 2026
READING TIME
14 min read
TOPIC
Supply Chain Security
Joyfill npm packages ran a RAT when imported

On 29 July 2026, researchers described the compromise of two prerelease npm packages in the Joyfill ecosystem. The published artifacts contained remote-access code that ran when an application loaded the module, not as a conventional install script. That distinction matters: the commonly recommended npm install --ignore-scripts option could reduce lifecycle-script risk, but it would not stop code subsequently executed by an application’s require() or import.

According to Socket’s analysis published on 29 July, malicious code appeared in:

These are specific beta and release-candidate versions. There is no basis for automatically treating every Joyfill release, the entire project or every application using its libraries as compromised. Organisations should nevertheless inspect more than direct dependencies in package.json: lockfiles, local caches, internal npm proxies, container images and historical CI artifacts can all retain an affected build.

What the research confirms

Socket analysed the published packages and found that the implant was present in generated bundles and visible in the accompanying source maps. This indicates that the unwanted code entered the artifact before publication or during the build process, rather than being appended solely by the registry after upload. That evidence does not determine how the compromise occurred. Plausible hypotheses include a publisher account, automation token, CI environment, build dependency or developer workstation, but the researchers did not conclusively attribute the initial access path.

The code started a primary Node.js RAT component on module import. The implant could collect system information, maintain contact with remote infrastructure and execute instructions received from an operator. Researchers also described a separate detached process branch that requested 23[.]27[.]13[.]43 at the /$/boot path. Requests carried the distinctive Sec-V: A9-0135-3 header.

The most unusual technical feature was a command-and-control resolver based on public blockchain networks. The code queried sources in the Tron, Aptos and BNB Smart Chain ecosystems to recover a current contact point. The blockchain was not the malware server itself. It acted as a public, distributed address book from which the implant could retrieve an intermediate value leading to operator infrastructure.

Why import-time execution changes the defence model

Many teams associate npm risk primarily with preinstall, install and postinstall fields. Disabling those hooks is a valuable layer: it makes automatic execution during dependency retrieval harder. It does not establish that a library is safe.

JavaScript and Node.js intentionally run module initialisation code on first load. If malicious logic sits inside a library’s main bundle, the application can launch it during startup, component rendering, a unit test or a build task. Exposure can therefore occur on:

  • a developer laptop running a local server;
  • a CI runner executing tests or a build;
  • a server-side rendering service loading the package in the backend;
  • documentation generators and Storybook jobs;
  • test processes with access to environment secrets;
  • a container launched long after its dependencies were downloaded.

That is why an investigation cannot stop after reviewing npm install logs. Responders must establish where and when the module was actually loaded.

Blockchain as a resilient C2 resolver

A conventional implant may contain a hard-coded domain or IP address. Defenders can block the domain, add it to DNS filters, report its hosting or sometimes sinkhole it. If code instead reads a value from a public blockchain, an operator may try to update the pointer without publishing another package version.

This does not make the communication invisible. Enterprise telemetry can still expose:

  • connections to blockchain API gateways or nodes that are unusual for a build process;
  • a sequence in which a process reads a value and then connects to a newly discovered host;
  • Node.js spawning child processes;
  • a mismatch between a UI package’s declared purpose and its network behaviour;
  • new files, persistence activity or reads from credential directories.

Breachroad’s conclusion is that detection should not depend solely on a static C2 blocklist. Behaviour is the stronger rule: a layout library has no legitimate reason to discover an endpoint across three blockchains and then execute operating-system commands.

Does this prove DEV#POPPER or PolinRider activity?

Socket identified similarities to activity tracked as DEV#POPPER and to tooling associated with PolinRider. The Hacker News report from 29 July discusses that context as well. These are code and tradecraft similarities, not public proof that a particular operator conducted this compromise.

An incident report should preserve three confidence levels:

  1. high confidence that the specified versions contained an unwanted remote-access capability;
  2. a moderate assessment that the implementation is related to previously observed tooling;
  3. insufficient public evidence to attribute the operation to a named state, group or individual.

Separating these levels prevents an attractive but unverified actor label from driving containment decisions.

How to assess exposure

Start by finding the exact version numbers in package-lock.json, npm-shrinkwrap.json, yarn.lock, pnpm-lock.yaml, SBOM manifests and artifact history. Absence from the current branch is not enough: an affected build may have been produced earlier while its container remains deployed.

Then review:

  • npm caches on workstations and runners;
  • internal Artifactory, Nexus, Verdaccio or other package proxies;
  • OCI image layers and packages in active deployments;
  • CI logs covering both dependency retrieval and test execution;
  • EDR telemetry for Node.js and child processes;
  • DNS, proxy, NetFlow and egress firewall data for infrastructure in the research;
  • use of npm, GitHub, GitLab, cloud and registry credentials available to potentially affected environments.

Do not equate “the package was downloaded” with “the RAT definitely ran.” Download evidence establishes artifact presence; execution requires process, network or behavioural evidence. Conversely, the absence of one proxy IOC does not exclude execution because the infrastructure resolver was designed to be dynamic.

An incident response plan

If either version is present, treat its environment as potentially affected until the evidence narrows the scope:

  1. stop promotion of dependent builds and isolate live workloads;
  2. remove the version from manifests, lockfiles, caches, proxies and base images;
  3. rebuild artifacts from clean, verified sources instead of patching an existing container;
  4. inventory every secret accessible to the Node.js process;
  5. revoke and replace credentials whose access is a credible scenario;
  6. review account, token and key activity from the first possible execution time;
  7. preserve samples, lockfiles, hashes, logs and images for forensic analysis;
  8. determine whether modified artifacts were republished elsewhere in the organisation.

Rotating every secret “just in case” can be operationally expensive, but an overly narrow rotation leaves a durable path back in. Prioritise high-impact credentials: npm publication, repository write access, container registries, cloud roles, deployment keys and production secrets visible to a runner.

Controls that reduce the next supply-chain incident

No single control stops this class. A stronger model combines:

  • pinned dependencies and deterministic lockfiles;
  • quarantine for new and prerelease versions before production approval;
  • comparison of package contents against its repository and expected build;
  • an SBOM for every release;
  • restricted egress from runners and workloads;
  • short-lived credentials instead of static tokens in environment variables;
  • separation of dependency installation, testing and publication;
  • alerts for unusual Node.js network activity and child processes;
  • a private proxy with version-approval policies;
  • rehearsed supplier-compromise response.

A prerelease suffix should not be treated as a harmless version attribute. Beta packages often run in test environments, and those environments are frequently connected to repositories and CI systems. Policy can require explicit approval for prereleases and automatically prevent their promotion to production.

Source findings versus Breachroad conclusions

The sources confirm the exact versions, RAT functionality, import-time execution, blockchain sources, identified infrastructure and the implant’s visibility in source maps. They do not publicly establish the initial compromise path or the number of organisations in which code actually executed.

Our recommendation to prioritise historical builds and runner credentials is an inference from the environments where the module could have loaded. It is not a claim that every Joyfill user lost credentials.

What to do today

  • search all lockfiles and SBOMs for the two exact versions;
  • block their retrieval through the corporate package proxy;
  • review Node.js processes, blockchain/API traffic and report IOCs;
  • replace secrets accessible in environments with confirmed execution;
  • introduce quarantine for new prereleases;
  • rehearse the path from package detection to recall of every dependent artifact.

npm compromise is a people, process and architecture problem, not only a dependency-scanner problem. Our cybersecurity and secure-development training helps development and operations teams recognise supply-chain risk and escalate it correctly. The technical foundations are also covered in our guides to software supply-chain attacks and the TeamPCP campaign.

If you need to establish the organisation’s real exposure, an IT security audit can cover pipelines, artifact repositories, secret management and response telemetry. The immediate priority remains removing the specified versions and determining whether they were only retrieved or actually executed.

Make credential rotation evidence-led

Rotation scope should combine where the module ran, when it ran and which privileges were available. A version present only in an isolated proxy cache does not justify treating every corporate identity as compromised. Execution on a shared runner with a production cloud role creates a much wider scope.

For each environment, record the possible execution window, process identity, mounted paths, environment variables, dynamically issued tokens, reachable services and available process, DNS and egress evidence. Classify credentials as exposed, potentially exposed or out of reach, and preserve the rationale. Our Cyber Threat Intelligence lifecycle shows how a public report becomes collection requirements and then an operational decision.

After rebuilding, ensure that a proxy cache or rollback cannot restore the package. Retest the clean lockfile, artifact hashes, SBOM absence and application behaviour after startup. The Breachroad Academy provides safe foundations in supply-chain and access management without requiring suspicious samples.

The investigation’s decisive result is not a repository count. It is an evidence-backed answer to whether code executed, what trust it inherited and which durable access paths were revoked.

SHARE / COPY