Votre assistant piloté par l'IA obéit à ses instructions environ 99 % du temps, mais c'est dans ce 1 % manquant que les attaquants frappent. En soumettant un prompt conçu à cet effet, un utilisateur malveillant peut amener le modèle à invoquer des fonctions qu'il ne devrait pas utiliser, volant ainsi des données ou effectuant des actions privilégiées. La solution ne consiste pas à utiliser une formulation plus polie, mais à traiter cette faille comme un problème d'autorisation et à retirer les outils dangereux de la portée du modèle.

Pourquoi l'injection de prompt n'est pas qu'un simple problème de formulation

Les développeurs tentent souvent de renforcer les agents avec des avertissements en majuscules, des règles numérotées ou des clauses du type « ne pas appeler les fonctions d'administration ». Ces défenses partent du principe que le modèle obéira à une phrase disant « ne faites pas X ». En pratique, on peut amener le modèle à ignorer l'instruction en reformulant la requête, en lui faisant jouer un rôle différent ou en ajoutant simplement un contexte supplémentaire. La frontière linguistique est négociable ; le prompt de l'attaquant est illimité et ne coûte rien à tester.

La véritable vulnérabilité réside dans la liste d'outils que l'agent reçoit. Lorsque le schéma du prompt contient une fonction qui accorde des droits d'administrateur, le modèle dispose désormais d'une carte vers ce pouvoir. Même si le prompt indique « ne l'utilisez pas pour les clients », le modèle peut toujours être persuadé de l'appeler car la fonction existe dans son environnement d'exécution. Le problème est donc un écart d'autorisation : le système expose des capacités privilégiées à un appelant qui n'y a aucun droit.

Sécuriser les agents en limitant l'exposition

Le moyen le plus simple de combler cette lacune est de cesser de donner au modèle l'accès à des outils qu'il n'est pas autorisé à utiliser. Considérez la liste d'outils comme une clé API : si la clé est absente, l'appel ne peut pas avoir lieu. Aucune formulation astucieuse ne peut invoquer une fonction qui ne figure pas dans le contexte actuel.

La mauvaise méthode

Prompt: “You are an assistant. Do not use the adminDeleteUser function for regular customers.”

Le modèle voit toujours adminDeleteUser dans sa boîte à outils et peut être piégé pour l'invoquer.

La bonne méthode

Prompt schema for a regular customer: { “functions”: [ “searchCatalog”, “placeOrder” ] }

adminDeleteUser n'apparaît jamais, le modèle n'a donc aucun moyen de l'appeler.

Trois règles pratiques pour les développeurs

  1. Construire les listes d'outils par requête – Générez le catalogue de fonctions de manière dynamique, en fonction des permissions de l'appelant authentifié. Un client ne voit que les fonctions dont il a besoin ; un administrateur voit l'ensemble complet.
  2. Privilégier la fermeture par défaut – Si l'identité de l'utilisateur ne peut pas être vérifiée, renvoyez une liste vide plutôt qu'une solution de repli générique de type « tous les outils sont disponibles ». Cela garantit qu'une requête non authentifiée n'acquerra jamais un pouvoir inattendu.
  3. Éviter l'état partagé – Lors de la mise en cache des définitions d'outils, n'écrivez jamais de données spécifiques à un utilisateur sur un objet partagé. Utilisez le copy-on-write ou des copies par session afin que les permissions d'un utilisateur ne puissent pas déborder sur la requête d'un autre.

Si le schéma présenté à un utilisateur ordinaire semble identique à celui présenté à un administrateur, la frontière de sécurité reste le texte du prompt, et les prompts ne constituent pas un mécanisme de sécurité fiable.

Ce qui nous a menés ici

L'injection de prompt est apparue lorsque les développeurs ont commencé à intégrer des modèles de langage étendus (LLM) dans des flux de production nécessitant que le modèle appelle des API externes, exécute du code ou modifie des bases de données. Le « raisonnement » du modèle est guidé par un prompt qui inclut également une liste d'outils disponibles. Les premiers prototypes partaient du principe que le modèle obéirait à une règle en langage naturel telle que « ne supprimez pas les enregistrements pour les non-administrateurs ». Les attaquants ont rapidement démontré que quelques phrases supplémentaires pouvaient contourner ces règles, poussant le modèle à appeler la même fonction de suppression malgré tout.

La première réaction de la communauté a été de durcir le langage des prompts, d'ajouter des clauses « ne faites jamais X » ou d'intégrer des filtres regex qui suppriment les jetons suspects. Ces mesures ont réduit les utilisations abusives accidentelles, mais n'ont pas arrêté un adversaire déterminé qui pouvait simplement reformuler la requête. La cause sous-jacente — l'exposition de fonctions privilégiées à un appelant non fiable — est restée.

Qui gagne, qui perd

Les entreprises qui adoptent une délimitation des outils par requête obtiennent une frontière claire et applicable. Leurs agents peuvent être déployés à grande échelle sans craindre qu'un seul prompt malformé ne déverrouille des capacités d'administration. Les équipes de conformité apprécient également la piste d'audit : la liste des fonctions envoyées au modèle est un artefact concret qui peut être journalisé et examiné.

Les développeurs qui s'appuient uniquement sur des protections par prompt continuent de faire face à une cible mouvante. Leurs agents peuvent sembler fonctionnels lors des tests, mais pourraient être compromis en conditions réelles, entraînant des violations de données, des transactions non autorisées ou des violations de conformité. Le coût d'une brèche dépasse de loin l'effort nécessaire pour construire une liste d'outils dynamique.

Contre-argument : « De meilleurs prompts suffisent »

Certains soutiennent qu'avec suffisamment d'ingénierie d'instructions — prompts multicouches, messages système et apprentissage par renforcement à partir de la rétroaction humaine — on peut amener le modèle à respecter les clauses d'interdiction. La réalité est que les modèles de langage sont des générateurs probabilistes ; ils évaluent la suite la plus probable, et non une règle de sécurité stricte. Même avec des garde-fous affinés, une formulation inédite peut passer entre les mailles du filet, surtout lorsqu'un attaquant peut itérer indéfiniment à un coût nul. Les garde-fous sont utiles pour réduire le bruit, mais ils ne devraient pas constituer l'unique ligne de défense.

À surveiller ensuite

  • Des frameworks qui exposent le scoping des outils comme une API de premier ordre – Attendez-vous à de nouvelles bibliothèques vous permettant de déclarer des capacités par utilisateur et de supprimer automatiquement la liste des fonctions avant la construction du prompt.
  • Des « manifestes de fonctions » standardisés – Des groupes industriels pourraient définir un schéma JSON qui sépare les fonctions publiques des fonctions privilégiées, facilitant ainsi la génération de manifestes spécifiques à chaque requête.
  • L'application au moment de l'exécution (Runtime enforcement) – Certaines plateformes expérimentent l'exécution en bac à sable qui vérifie le jeton de l'appelant par rapport à la fonction invoquée, ajoutant ainsi une seconde couche au-delà du scoping du prompt.

La conclusion est claire : traitez l'injection de prompt comme une faille d'autorisation. En retirant les outils non autorisés de la boîte à outils du modèle, vous éliminez la surface d'attaque qu'un prompt habilement formulé cherche à exploiter. Les prompts peuvent guider le comportement ; ils ne peuvent pas remplacer un contrôle d'accès approprié.