Le 14 janvier 2026, j'ai revendiqué un package sur npm appelé react-codeshift.
Je n'en étais pas l'auteur. Je n'avais jamais écrit une ligne de code pour celui-ci. Le package n'avait jamais existé. Personne ne l'avait jamais publié. Et pourtant, 237 dépôts GitHub le référençaient déjà, demandant aux agents IA de l'installer. Certains d'entre eux essayaient réellement. Je recevais des téléchargements pour un package que je venais de publier, et qui ne contenait rien.
D'où venait ce nom ? Un LLM l'avait inventé. Comment s'est-il propagé à 237 dépôts ? Par des fichiers de compétences d'agent. Copiés-collés, forkés, traduits en japonais, jamais vérifiés. Je l'ai trouvé et revendiqué avant que quiconque d'autre ne puisse le faire.
La recherche
En juillet 2025, j'ai commencé à me pencher sur Problèmes de confusion liés à npx. Il s'agit de noms de paquets npm qui apparaissent dans la documentation/le code, mais qui n'ont jamais été publiés. L'idée était simple : récupérer package.json les scripts et les fichiers README sur l'ensemble de npm pour npx <package> des patterns et vérifier si ces packages existent réellement. Il s'avère que beaucoup d'entre eux n'existent pas.
Puis, l'attaque S1ngularity a eu lieu, et j'ai mis mes recherches en suspens. À l'approche des fêtes, je m'y suis remis. Cet article ne couvre qu'une partie de ces recherches. D'autres suivront.
Présentation de react-codeshift
J'ai repris la recherche en décembre et j'ai décidé de l'étendre pour indexer également GitHub en recherchant des références à npx commandes. react-codeshift est apparu fréquemment. Plus de 200 dépôts. Au moment où je l'ai revendiqué, ce nombre était passé à plus de 237.

Le fait est que, react-codeshift n'existait pas. Du moins, pas avant que je ne le revendique. Mais le nom semble légitime. Deux packages réels existent :
Un LLM a mélangé tout ça et a halluciné react-codeshift. Un nom plausible pour un outil qui n'existe pas. Un classique.
La genèse
Je l'ai retracé jusqu'à un seul commit : 65e5cb0 dans le wshobson/agents référentiel, daté du 17 octobre 2025.
Ce commit a déversé 47 « Agent Skills » générées par LLM à travers 14 plugins. Aucune révision humaine apparente. Au moins deux de ces compétences (react-modernization et dependency-upgrade) contenaient ceci :
npx react-codeshift --transform=react-codeshift/transforms/rename-unsafe-lifecycles.js ./src
npx react-codeshift --transform=react-codeshift/transforms/new-jsx-transform.js ./srcSemble légitime. Sonnait légitime. Les chemins de transformation reflètent la structure des vrais codemods.
Sauf qu'il n'existait pas.
Compétences : La nouvelle surface d'attaque
Nous avons déjà vu des cas de typosquatting et d'AI slop packages. Il s'agit ici d'un cas réel de slopsquatting, et non d'une simple spéculation. Et cela se propage via Skills.
Les compétences sont une nouvelle norme : la spécification des compétences d'agent d'Anthropic, les plugins de code Claude, les serveurs MCP. Tous utilisent des fichiers de compétences pour indiquer aux agents d'IA ce qu'ils doivent faire. Ces fichiers ressemblent à de la documentation : Markdown, YAML, instructions en texte brut.
Mais ce sont des instructions exécutables. Lorsqu'un agent d'IA charge un fichier de compétences, il suit les commandes. Il ne vérifie pas si npx react-codeshift existe. Il l'exécute simplement.
Lorsque npx ne trouve pas un package localement, il invite à :
Besoin d'installer les packages suivants :
react-codeshift
Continuer ? (o)L'agent appuie sur 'o'. La plupart des gens feraient de même. Les agents sont comme nous à cet égard. L'aveugle guidant l'aveugle, à grande échelle.
Preuve de tentatives d'exécution actives
Après avoir revendiqué le package, j'ai observé la télémétrie de téléchargement :
Les paquets normaux enregistrent entre 60 et 100 téléchargements le premier jour (miroirs de registre, scanners de sécurité), puis plus aucun par la suite. Personne n'essaie réellement de les utiliser.
Mais react-codeshift? Ce flux persistant de 1 à 4 téléchargements par jour ? Ceux-là sont réels. Ce sont des agents d'IA qui suivent des instructions de compétences et déclenchent des téléchargements npx.
Les compétences sont utilisées. Le package halluciné est exécuté. Si je ne l'avais pas revendiqué en premier, un attaquant aurait pu le faire.
Le modèle de propagation
Les 237 dépôts remontent à la même source. Le modèle est presque entièrement constitué de forks directs :
wshobson/agents(origine)- Environ 100 forks conservant le chemin exact :
plugins/framework-migration/skills/react-modernization/SKILL.md - Un utilisateur l'a copié dans plus de 30 de ses propres dépôts.
- Quelques réorganisations dans différentes structures de répertoires.
- Même une traduction japonaise !
- Un dépôt a basculé
npxàbunx. Même package halluciné, runner différent.
Il n'y a pas que npx.
Le même schéma s'applique à chaque package runner :
npx react-codeshiftbunx react-codeshiftpnpm dlx react-codeshiftyarn dlx react-codeshift
Ils se résolvent tous vers le même registre npm. Ils demandent tous confirmation avant l'installation. Ils sont tous approuvés sans la moindre hésitation. Si un LLM hallucine un nom de package sous une forme, il l'hallucinera également sous d'autres.
C'est viral, mais superficiel. Pas de dépôts majeurs. Pas de projets très étoilés. Juste des agents enseignant à d'autres agents à utiliser un package qui n'existait pas. Des agents à l'infini. Un système auto-améliorant, en quelque sorte.
Pourquoi cela est important
Ce n'était pas une brèche massive. Personne n'a été compromis. Le package est désormais un placeholder sûr.
Mais c'est une étude de cas utile sur la façon dont ces choses se propagent :
- Les LLM hallucinent des noms de packages plausibles. Surtout pour les outils spécifiques à un domaine où les conventions de nommage sont prévisibles.
- Les compétences sont copiées-collées sans révision. Elles ressemblent à de la documentation, elles ne bénéficient donc pas du même examen minutieux que le code.
- Les agents suivent les instructions à la lettre. C'est leur travail.
- npx invite à l'action, les humains approuvent. La friction est suffisamment faible pour que la plupart des gens appuient simplement sur 'y'.
- Les noms non revendiqués sont attribués selon le principe du premier arrivé, premier servi. N'importe qui peut les enregistrer.
Je suis tombé sur celui-ci et je l'ai revendiqué. Le modèle mérite d'être compris.
Que devriez-vous faire ?
Si vous maintenez des compétences d'agent ou des outils d'IA :
- Traitez les compétences comme du code, et non comme de la documentation. Passez-les en revue. Auditez-les. Gérez-les en version avec la même rigueur que le code source.
- Vérifiez que les noms de paquets existent. Avant de committer toute
npx <package>instruction, vérifiez que le paquet est réel et publié par la personne que vous pensez l'avoir publié. - Recherchez dans votre base de code. Exécutez
grep -r "npx react-codeshift"et corrigez les correspondances. Remplacez par les outils appropriés :npx jscodeshiftpour les codemods génériquesnpx react-codemodpour les transformations spécifiques à React
Indicateurs de compromission
package npm : react-codeshift
La vue d'ensemble
Les compétences sont le nouveau code. Elles n'en ont pas l'apparence. Ce sont du Markdown, du YAML et des instructions conviviales. Mais elles sont exécutables. Les agents IA les suivent sans demander « ce package existe-t-il réellement ? »
C'était une hallucination. Elle s'est propagée à 237 dépôts. Elle a généré de réelles tentatives de téléchargement. La seule raison pour laquelle elle n'est pas devenue un vecteur d'attaque est que je suis intervenu en premier.
La chaîne d'approvisionnement vient de s'enrichir d'un nouveau maillon, issu des rêves des LLM. Ce n'est là qu'une des conclusions de la recherche sur la confusion npx. D'autres suivront.
Sécurisez votre logiciel dès maintenant.



.avif)
