---
title: "ChainDrop: the npm worm that survives removal by rewriting VS Code and Claude Code configuration"
description: "ACN bulletin on ChainDrop: over 400 compromised npm packages, a preinstall script running before the decision, persistence in developer tool configuration."
url: https://csidia.com/en/notes/chaindrop-npm-worm-configurazione-strumenti/
lang: en
date: 2026-08-06
label: "Observatory"
publisher: CSIDIA S.r.l. (https://csidia.com/)
italiano: https://csidia.com/note-operative/chaindrop-npm-worm-configurazione-strumenti/
---

# ChainDrop: the npm worm that survives removal by rewriting VS Code and Claude Code configuration

On 5 August 2026 Italy's national CSIRT (ACN) published bulletin BL01/260805/CSIRT-ITA on "ChainDrop: a self-propagating worm campaign in the npm ecosystem", rated criticality "Medium (64.97)". The summary: over 400 compromised npm packages, from different maintainers and organisations. Among the names involved: keyv 6.0.0, flat-cache 6.1.24, file-entry-cache 11.1.6, cache-manager 7.2.10, cacheable 2.5.1, cacheable-request 13.0.20, @cacheable/memory 2.2.1, @cacheable/node-cache 3.1.2, @cacheable/utils 2.5.1, @cacheable/net 2.1.1, ecto 5.0.1. The bulletin is under Sources, below — we do not translate it wholesale here, we read it for whoever has to decide what to do next. It exists only in Italian; every quotation from it below is our own translation of the original text.

## The trust boundary isn't the model: it's the package

Anyone worrying about which artificial intelligence to adopt, and not about what an `npm install` actually runs, is watching the wrong door. The compromised releases introduce a preinstall script that launches `setup.mjs`, which loads the `Math_Symbol.js` payload (or equivalent variants). The bulletin is unambiguous about when this happens: "the execution of the malicious content takes place during the package installation phase, before the npm procedure completes" (our translation). There is no moment at which anyone decides whether to trust it: execution precedes the decision.

The payload, moreover, does not behave the same way everywhere: it distinguishes a development workstation from a CI/CD runner, and on the latter it "can remain attached to the build process to access the secrets, temporary tokens and credentials available within the pipeline's own context". The attack does not target the single laptop: it targets the point in the infrastructure where credentials are most concentrated and least watched — the pipeline that runs while no one is looking. [We had already documented a cycle that precedes human oversight](https://csidia.com/en/notes/deepseek-telegram-attacco-informatico-autonomo), there with an offensive agent acting without an operator step by step; here the operator does not even get the chance to intervene, because the package has not yet finished installing.

## Persistence reaches the agent's configuration too

The most useful point in the bulletin, for anyone running AI-assisted development tools, sits in the section on persistence and evasion: the malware modifies "configuration files associated with development environments and GitHub repositories, including components linked to Visual Studio Code and Claude Code, in order to maintain persistence on systems and enable further executions even after the original dependency has been removed". On top of that come advanced obfuscation and encrypted exfiltration of the information gathered.

This should be read with technical coolness, without alarmism and without laying blame on Microsoft or Anthropic: the flaw is not in their products. It is that an untrusted process — the preinstall script of a compromised package — was able to write the configuration of a trusted tool. An editor's or an agent's configuration is a file like any other: whoever controls it decides what the tool runs on the next restart, even after the offending dependency has been removed from the project — uninstalling the package does not touch what that package has already written elsewhere on disk. This is exactly the extra surface for anyone running development agents on their own systems: not because the agent is vulnerable in itself, but because its configuration is reachable by any process with sufficient permissions on the same machine.

## Stolen credentials publish more packages

What the malware collects is not generic: "environment variables, npm tokens, GitHub tokens, SSH keys, cloud credentials and secrets used in automation pipelines". And it is what is done with them that makes ChainDrop a worm, not a simple theft: the credentials obtained are used "to access repositories, cloud services and npm accounts, enabling the automated publication of further compromised packages". It is a supply chain that feeds on itself — every compromised maintainer becomes the vector to the next one.

That is why the list of eleven packages above is a snapshot, not a perimeter, and ACN itself warns of it: "owing to the self-propagating mechanism, the perimeter of affected versions is extremely dynamic. It is recommended not to limit verification to the version numbers indicated above alone, but to extend the check to any release published within the campaign's time window". A check run today against eleven precise names is reassuring, and nothing more: the question that still holds, three weeks from now, is a different one.

## The right question isn't "which packages" — it's "which token"

Asking "are we exposed to these eleven packages?" is the wrong question, because the answer expires the moment you get it. The one that holds is: which token, present on which machine, could publish in our organisation's name? And if we revoked it today, could we say with certainty what stops working? If the second answer doesn't exist — if no one in the company knows which builds, which deployments, which automations depend on that token — the problem isn't ChainDrop: it's that the credential inventory doesn't exist, and ChainDrop has only made that visible.

The bulletin's mitigations should be read with that in mind, not as a box to tick once. The first step is blocking automatic execution: `--ignore-scripts` during analysis or remediation stops preinstall and postinstall hooks from firing on their own; updating npm — and evaluating `min-release-age` — cuts the risk of automatically pulling a release that has only just been published, still within the window before anyone has flagged a compromised package. The second is searching: inside `package-lock.json`, `yarn.lock` and `pnpm-lock.yaml`, to check whether compromised names and versions are already in the codebase, and on the filesystem, for files such as `setup.mjs`, `Math_Symbol.js` or `math_init.js`. The third is pinning known-good versions with `overrides` or `resolutions`, so an automatic update doesn't reintroduce what has just been excluded.

Then comes the part that costs more, and is therefore put off more often: revoking and regenerating npm tokens, GitHub credentials, cloud keys and CI/CD secrets accessible from the affected host; clearing the caches; verifying the artefacts produced during the exposure window; rebuilding images and CI/CD runners from trusted sources, not from a backup that might already contain the payload. And finally checking, not assuming, that changes to repositories, automated workflows and development-tool configuration files — "e.g. VS Code and Claude Code extensions and settings" — are the ones you authorised.

## Sources

- [ACN CSIRT Italia — Bulletin BL01/260805/CSIRT-ITA, ChainDrop: a self-propagating worm campaign in the npm ecosystem (Italian original)](https://www.acn.gov.it/portale/w/chaindrop-campagna-worm-auto-propagante-nell-ecosistema-npm)
- [Cyber Security Agency of Singapore — Ongoing npm Supply Chain Attack Affecting Keyv and Related Packages (AD-2026-009)](https://www.csa.gov.sg/alerts-and-advisories/advisories/ad-2026-009/)

Note by CSIDIA S.r.l. (Vignola, MO, Italy): https://csidia.com/en/notes/chaindrop-npm-worm-configurazione-strumenti/ · Who we are and what we do: https://csidia.com/en/at-a-glance/ · engagement@csidia.com
