Aller au contenu

Slopsquatting, paquets inventés par les assistants de code IA

Slopsquatting, paquets inventés par les assistants de code IA

Section intitulée « Slopsquatting, paquets inventés par les assistants de code IA »

Un assistant de programmation fondé sur l’intelligence artificielle (IA) propose parfois d’installer un paquet qui n’existe pas. Le slopsquatting consiste à enregistrer ce nom inventé sur un registre public pour que la prochaine installation récupère un code malveillant. La position défendue ici : aucune dépendance ne doit pouvoir entrer dans un projet directement depuis un registre public, qu’elle vienne d’un humain ou d’un modèle.

→ Lire l’explication complète de la marmotte

Le mécanisme : une hallucination prévisible devient une cible

Section intitulée « Le mécanisme : une hallucination prévisible devient une cible »

Un modèle de langage génère le nom de paquet le plus plausible dans le contexte, pas le nom vérifié. Pour une tâche courante, il produit souvent un nom composé de termes du domaine (flask-jwt-helper, requests-retry-auth) qui sonne juste et n’a jamais été publié. Le terme slopsquatting a été proposé en 2025 dans l’écosystème Python pour distinguer ce cas du typosquatting.

La différence avec le typosquatting est structurelle. Le typosquatting parie sur une faute de frappe humaine, aléatoire et dispersée. Le slopsquatting parie sur une erreur du modèle, et les travaux académiques publiés sur le sujet (notamment une étude présentée à USENIX Security 2025 sur les hallucinations de paquets) observent qu’une partie des noms inventés revient d’une requête à l’autre. Un nom qui revient est un nom qu’un attaquant peut découvrir en interrogeant les modèles lui-même, puis réserver sur PyPI (Python Package Index) ou le registre npm de Node.js. Il se distingue aussi de la confusion de dépendances, qui exploite un nom interne à une organisation publié sur un registre public : ici, le nom n’appartient à personne avant l’attaquant.

Une démonstration publique en 2024 a enregistré sur PyPI un nom halluciné, sous forme de paquet vide, et observé des installations réelles. Rien de sophistiqué : il suffisait d’être là le premier.

Surface d’attaque dans la chaîne de dépendances

Section intitulée « Surface d’attaque dans la chaîne de dépendances »

Le moment critique est l’installation, pas l’import.

  • Scripts d’installation npm : les scripts preinstall et postinstall s’exécutent à l’installation, avec les droits de l’utilisateur ou du job d’intégration continue, donc avec accès aux variables d’environnement et aux jetons de publication.
  • Distributions source Python : installer une distribution source (sdist) exécute le code de construction du paquet. Une roue (wheel) précompilée n’exécute rien à l’installation, mais tout code au niveau module s’exécute au premier import.
  • Agents de code autonomes : un assistant autorisé à lancer des commandes dans un terminal enchaîne suggestion et pip install sans relecture humaine. La fenêtre entre hallucination et exécution tombe à zéro.
  • Documentation contaminée : un nom halluciné recopié dans un README ou un tutoriel se propage aux humains, qui l’installent sans assistant.

Vingt ans de gestion de dépendances apprennent que pip install depuis Internet dans un job de CI (Continuous Integration) revient à exécuter le code de n’importe qui, avec les secrets de déploiement en variables d’environnement ; l’IA n’a pas créé le problème, elle a seulement accéléré le débit des inconnus.

Contre-mesures : registre maîtrisé, verrouillage et délai

Section intitulée « Contre-mesures : registre maîtrisé, verrouillage et délai »

La règle centrale : les postes de développement et la CI ne résolvent les dépendances que via un registre interne (proxy de type Nexus, Artifactory, devpi ou Verdaccio) qui n’expose que des paquets approuvés. L’accès direct à pypi.org et registry.npmjs.org est bloqué au niveau du proxy réseau sortant. Un paquet inventé n’y figure pas : l’installation échoue, ce qui est exactement le comportement voulu.

Autour de ce registre :

  1. Verrouillage par empreinte : pip install --require-hashes -r requirements.txt (fichier produit par pip-compile --generate-hashes) et npm ci, qui respecte les empreintes du package-lock.json. Une dépendance absente du fichier de verrouillage fait échouer la construction.
  2. Pas d’exécution à l’installation : npm ci --ignore-scripts par défaut, avec liste d’exceptions ; côté Python, pip install --only-binary=:all: refuse les distributions source.
  3. Délai de quarantaine : certains gestionnaires refusent les versions trop récentes (--exclude-newer pour uv, minimumReleaseAge pour pnpm). Un paquet opportuniste publié la veille ne passe pas.
  4. Agents sous contrôle : toute commande d’installation proposée par un agent exige une validation humaine explicite.

Ce que ces mesures ne garantissent pas : elles bloquent un paquet inconnu, pas un paquet légitime compromis ni un paquet malveillant approuvé par erreur. L’approbation d’une nouvelle dépendance reste une décision humaine, qu’il faut outiller.

Vérifier un paquet suggéré avant de l’approuver

Section intitulée « Vérifier un paquet suggéré avant de l’approuver »

Avant d’ajouter un nom proposé par un assistant à la liste du registre interne, trois questions : le paquet existe-t-il, depuis quand, et qui le publie ? Les registres publics exposent ces métadonnées sans authentification. Prérequis : curl, jq, npm.

Fenêtre de terminal
PAQUET="nom-suggere-par-l-assistant"
# PyPI : l'API JSON (JavaScript Object Notation) répond 404 si le paquet n'existe pas
curl -fsS "https://pypi.org/pypi/$PAQUET/json" | jq '{
nom: .info.name,
auteur: .info.author,
depot: .info.project_urls,
nb_versions: (.releases | length),
# date du tout premier fichier publié, toutes versions confondues
premiere_publication: ([.releases[][]?.upload_time_iso_8601] | min)
}' || echo "Absent de PyPI : nom probablement inventé"
# npm : date de création, mainteneurs, dépôt source et présence de scripts d'installation
npm view "$PAQUET" time.created maintainers repository.url scripts --json \
|| echo "Absent du registre npm : nom probablement inventé"

Un paquet créé récemment, sans dépôt source, avec une seule version et un script postinstall coche toutes les cases d’une mauvaise surprise. L’absence pure est le cas le plus favorable : l’hallucination est détectée avant qu’un attaquant ne l’ait réservée. Le signaler aux équipes évite qu’un autre développeur retombe sur le même nom demain.

Le contexte plus large de la chaîne logicielle est dans la rubrique Développement, et la vue d’ensemble dans IA. Les failles de logique dans le code généré lui-même relèvent de la revue de code et se traitent à part.

Sans registre maîtrisé ni verrouillage, une dépendance hallucinée qui s’installe avec succès est inscrite dans le fichier de dépendances et se réinstalle ensuite sur chaque poste et dans chaque pipeline, bien après la conversation qui l’a suggérée. Le script d’installation s’exécute dans l’environnement de construction, où il lit les jetons de publication de paquets et d’images : l’attaquant peut alors publier au nom de l’organisation, ce qui étend la compromission aux utilisateurs en aval. Et comme rien ne relie le paquet à une suggestion d’assistant, l’analyse après incident ne remonte pas à l’origine, donc le même nom revient au prochain projet.

Les programmeurs réutilisent des morceaux de code écrits par d’autres, appelés paquets, qu’ils téléchargent depuis de grands catalogues publics en ligne. N’importe qui peut y publier un paquet sous un nom encore libre. Les assistants d’intelligence artificielle qui aident à programmer proposent souvent d’installer un paquet, mais ils fabriquent le nom qui leur paraît le plus probable, sans vérifier qu’il existe. Parfois il n’existe pas, et l’assistant propose souvent le même faux nom à plusieurs personnes. Un pirate peut repérer ces faux noms en posant les mêmes questions, puis publier sous ce nom un paquet piégé. Le prochain programmeur qui suit le conseil installe alors le piège. Certains paquets exécutent du code dès leur installation, avant même d’être utilisés : ce code peut voler les mots de passe et les clés présents sur l’ordinateur ou sur le serveur qui fabrique le logiciel. Pour se protéger, l’entreprise n’autorise que les paquets déjà vérifiés, rangés dans un catalogue interne, et bloque l’accès direct aux catalogues publics. Elle enregistre aussi l’empreinte exacte de chaque paquet, pour refuser tout ce qui n’est pas prévu, et interdit l’exécution de code pendant l’installation. Avant d’ajouter un nouveau paquet, quelqu’un vérifie qu’il existe, depuis quand, et qui le publie.

À lire aussi

Pages voisines