Abus de LLMO : piéger les agents de code IA via la doc des paquets
Le rapport PromptMink de ReversingLabs (juin 2026) montre un groupe nord-coréen rédigeant la documentation de paquets npm pour paraître crédible aux agents de code LLM, afin que l'agent recommande et installe une dépendance malveillante.
De quoi s’agit-il ?
En juin 2026, ReversingLabs a publié une analyse d’une campagne de chaîne d’approvisionnement baptisée PromptMink, attribuée au groupe lié à la Corée du Nord Famous Chollima. La nouveauté ne réside pas dans le malware, mais dans la cible. Plutôt que de piéger un développeur humain, les attaquants rédigent la documentation des paquets pour convaincre un grand modèle de langage que le paquet est la bonne dépendance pour la tâche en cours. ReversingLabs nomme cette technique abus de LLM Optimization (LLMO) et injection de connaissance. L’objectif, selon eux, est « de rendre le LLM susceptible de recommander l’usage du paquet malveillant en rendant la documentation aussi crédible et adaptée que possible au projet sur lequel travaille l’agent de code ». Il s’agit d’une description de classe d’attaque, pas d’un exploit actionnable.
La campagne n’est pas théorique. ReversingLabs a fait remonter les paquets de charge malveillante à septembre-octobre 2025, et confirme qu’ils ont atteint de vrais agents : un commit du 28 février 2026 sur un agent de trading crypto open source, openpaw-graveyard, a ajouté la dépendance-appât dans un commit co-signé par Claude Opus. Un second cas est apparu sur une plateforme où des agents LLM publient sur leur travail, où un bot expliquait avoir utilisé l’un des paquets-appâts parce qu’il « contenait une fonction dont il avait besoin ».
Comment ça marche
L’attaque sépare le leurre de la charge utile sur deux couches de paquets, ce qui la rend durable.
Couche Rôle Exemple (d'après le rapport)
------------- ---------------------------- --------------------------------
1. "Appât" Paquet propre, d'apparence @solana-launchpad/sdk
légitime, doc soignée. Liste (ne contient aucun code
la couche 2 en dépendance malveillant)
transitive.
2. "Charge" Infostealer tiré @hash-validator/v2 ->
automatiquement à l'install. @validate-sdk/v2 (code identique,
Renommé à chaque détection. nouveau nom après chaque retrait)
Deux choix de conception font tout. D’abord, la documentation est optimisée pour un lecteur machine, pas humain : texte de README convaincant, types TypeScript, structure sémantique qui amènent un agent à conclure que le paquet convient au projet en cours. Ensuite, le comportement malveillant est caché là où les LLM ne regardent pas. À mesure que les détections augmentaient, les opérateurs ont déplacé les charges du JavaScript facilement analysable vers des add-ons Node.js Rust pré-compilés (via NAPI-RS) : le code qu’un agent pourrait lire reste propre pendant que le binaire vole — exfiltration des secrets d’environnement, dépôt de clés SSH, archivage de données vers l’infrastructure de l’attaquant.
Comme le paquet-appât propre n’a jamais besoin de changer, les attaquants préservent sa réputation et se contentent d’y injecter une charge fraîchement renommée à chaque détection — la même astuce qui met en échec les listes de blocage par nom.
Pourquoi c’est important
Pendant des années, la principale défense comportementale contre ces attaques était la friction humaine : un développeur qui s’arrête sur un nom inconnu pour vérifier le nombre de téléchargements et l’historique du mainteneur avant de lancer npm install. Comme le souligne Brad Arkin (Socket) le 23 juin 2026, les agents IA suppriment précisément cette friction : ils résolvent une dépendance et poursuivent le build. L’efficacité est la surface d’attaque.
Cela transforme en arme la force de compréhension documentaire du LLM. C’est un cousin, côté chaîne d’approvisionnement, de l’empoisonnement des descriptions d’outils : le modèle fait confiance à un texte rédigé par l’attaquant et agit en conséquence. Cela diffère aussi des deux schémas déjà couverts — le slopsquatting, qui exploite les noms hallucinés, et le typosquatting de modèles, qui exploite les noms mal tapés. L’abus de LLMO n’a besoin d’aucun des deux : le nom du paquet est réel, la doc est excellente, et l’agent le choisit sur ses mérites — des mérites fabriqués.
Défenses
Aucun correctif ne règle ce problème, car rien n’est techniquement « cassé ». Les contrôles relèvent du processus et de l’hygiène du pipeline, et rejoignent les recommandations CISA/Five Eyes du 1er mai 2026, qui avertissent que les agents choisissent « plus souvent les descriptions persuasives ».
- Traitez les paquets suggérés par l’agent comme une catégorie de revue distincte et non fiable. Toute dépendance ajoutée automatiquement doit être revue (éditeur, ancienneté de la version, dépendances transitives) avant livraison — le moment de revue humaine que l’agent a sauté.
- Appliquez la politique de registre dans la CI/CD, pas seulement sur les postes. Mettez en liste blanche les paquets et versions approuvés pour qu’un agent ne puisse littéralement rien installer hors liste, quoi que dise la doc. Les garde-fous au niveau du registre s’appliquent quel que soit le mode d’introduction.
- Exigez une approbation humaine pour les actions à fort impact. La CISA range précisément l’ajout d’une dépendance dans un pipeline sensible dans cette catégorie.
- Détectez par le comportement, pas par le nom. Ces paquets ne portaient aucun CVE au moment de l’attaque ; les outils SCA qui ne comparent que les noms à des bases de vulnérabilités ne voient rien. Analysez ce que fait un paquet — et sachez que
--ignore-scriptsn’est qu’un contrôle partiel, contournable via les extensions natives. - Donnez à l’agent un oracle de réputation. ReversingLabs a montré qu’un agent de code, une fois relié à un serveur MCP de réputation de paquets, déconseillait correctement d’installer le paquet-appât. Fournissez aux agents des données factuelles plutôt que de faire confiance au marketing du paquet.
- Maintenez un SBOM. On ne peut pas réagir à une dépendance introduite par un agent que l’on ne voit pas après coup.
Statut
| Élément | Référence | Date | Notes |
|---|---|---|---|
| Premier paquet de charge détecté | ReversingLabs | 2025-09 | Début de la campagne à deux couches |
| Bascule vers charges Rust/NAPI-RS | ReversingLabs | 2026-03 | Échappe à la revue de code par LLM |
| Dépendance-appât ajoutée par un agent | commit openpaw-graveyard | 2026-02-28 | Co-signé par Claude Opus |
| Recherche publique (PromptMink) | ReversingLabs | 2026-06 | Attribution : Famous Chollima |
| Recommandations multi-gouvernementales | CISA / Five Eyes | 2026-05-01 | Listes blanches, approbation humaine, moindre privilège |
Le cadrage honnête n’est pas « un LLM s’est fait pirater ». C’est que la capacité d’un agent à lire et faire confiance à la documentation est désormais une surface d’attaque, et la parade consiste à cesser de laisser un paquet se décrire lui-même : vérifiez-le hors bande, verrouillez-le dans le pipeline, et gardez un humain sur l’installation de tout ce que l’agent a trouvé convaincant.
Sources
- → https://www.reversinglabs.com/blog/claude-promptmink-malware-crypto
- → https://www.techtimes.com/articles/319457/20260701/ai-coding-agents-skip-package-verification-attackers-are-exploiting-it.htm
- → https://socket.dev/blog/the-code-you-didnt-write-is-still-yours-to-defend
- → https://www.cisa.gov/resources-tools/resources/careful-adoption-agentic-ai-services