MVP DevelopmentMVP Development
Retour aux ressources

Comment prévenir le prompt injection : les garde-fous d'une vraie application LLM

9 min min read
How to Prevent Prompt Injection: Guardrails for a Real LLM App

Dès qu'une fonctionnalité LLM lit quelque chose que vous ne contrôlez pas entièrement, le message d'un utilisateur, un document, une page web récupérée par un outil, vous ouvrez un canal dans lequel un attaquant peut écrire. Le prompt injection, c'est du texte qui arrive par ce canal et qui tente de détourner les instructions du modèle au lieu de répondre à la question posée. Ce guide explique comment prévenir le prompt injection avec des défenses qui tiennent une fois que du trafic réel atteint votre application. Aucune d'entre elles ne rend un modèle totalement immunisé. La défense en profondeur augmente suffisamment le coût d'une attaque pour que la plupart des attaquants se tournent vers une cible plus facile.

Ce qu'est le prompt injection

Une application LLM fonctionne en transmettant un prompt au modèle : les instructions système écrites par votre équipe, plus tout ce que la requête ramène avec elle, le message d'un utilisateur, un paragraphe de document, la sortie d'un appel d'outil précédent. Le modèle prédit la suite du texte à partir de tout cet ensemble en même temps, en lisant les instructions et le texte récupéré comme un seul flux continu de tokens. Rien ne distingue une partie comme instruction fiable et une autre comme donnée non fiable. Le prompt injection, c'est du texte non fiable conçu pour être lu comme une instruction plutôt que comme un contenu à résumer ou une question à laquelle répondre. Un email de support qui dit au modèle qui le lit de divulguer des détails de compte qu'il ne devrait pas révéler. Une ligne dans une page web récupérée qui indique à un agent de recherche de sauter une vérification qu'il était censé effectuer. La formulation change à chaque fois. Le schéma, lui, reste fixe : un contenu que le modèle n'était pas censé suivre finit par être suivi quand même, puisqu'il n'a aucun moyen intégré de distinguer une instruction d'une donnée.

Injection directe et indirecte

L'injection directe est le cas le plus simple : quelqu'un tape dans votre interface de chat et tente de contourner ses instructions, en demandant au modèle d'ignorer son prompt système ou de répondre en dehors de son périmètre. Elle recoupe le jailbreaking, même si la cible diffère. Le jailbreaking vise généralement l'entraînement de sécurité propre au modèle. L'injection directe vise ce que votre application a spécifiquement demandé au modèle de faire. L'injection indirecte est celle qui prend les équipes au dépourvu. Le texte malveillant arrive sans que la personne en train de discuter n'en écrive le moindre mot : il se cache plutôt dans un document que votre assistant résume, une page web que votre agent de recherche lit, ou un ticket de support que votre outil de tri traite. Le modèle ne peut pas distinguer un paragraphe légitime d'une instruction dissimulée une fois que les deux ne sont plus que du texte dans son contexte. L'injection indirecte mérite plus d'attention qu'elle n'en reçoit habituellement. Filtrer ce qu'un utilisateur tape n'en arrête aucune, puisque l'utilisateur n'a jamais tapé l'attaque lui-même. La personne qui pose la question est souvent tout aussi surprise que vous.

Filtrer ce qu'un utilisateur tape n'arrête aucune attaque indirecte. L'instruction se trouve déjà dans un document, une page web ou un ticket que votre application allait lire de toute façon. Un garde-fou limité à la saisie utilisateur passe complètement à côté.

Pourquoi RAG et les agents élargissent la surface d'attaque

Un chatbot qui répond à partir d'un script fixe n'a pratiquement pas de surface d'attaque digne de ce nom. Ajoutez de la recherche documentaire et la situation change vite. Chaque document qu'un pipeline RAG ramène dans le contexte, un article d'aide, un contrat téléversé, un résultat de recherche web en direct, est un texte que le modèle va lire et potentiellement suivre. Élargissez les sources dans lesquelles il puise et vous élargissez les endroits où quelqu'un peut glisser une instruction. Les agents aggravent l'autre moitié du problème : les conséquences. Un chatbot piégé sur un sujet non autorisé fait perdre une conversation. Un agent piégé alors qu'il détient un outil capable d'envoyer un email, d'écrire dans une base de données ou d'appeler une API de paiement peut agir sur l'instruction qu'on lui a fait passer pour légitime. Le modèle fait exactement ce que son contexte lui dit de faire, et c'est justement le contexte qui a été compromis. La plupart des fonctionnalités LLM utiles ont besoin de recherche documentaire, d'accès à des outils, ou des deux. La vraie tâche consiste à traiter chaque passage récupéré et chaque appel d'outil comme un endroit qu'un attaquant pourrait atteindre.

Comment prévenir le prompt injection : les garde-fous qui font vraiment la différence

Demandez à cinq prestataires comment prévenir le prompt injection et vous obtiendrez cinq produits à acheter. Aucun ne règle le problème à lui seul. Ce qui tient la route en pratique, c'est de superposer les défenses pour qu'un seul échec ne suffise jamais à donner à un attaquant le résultat qu'il recherche. Commencez par la couche la plus faible : la hiérarchie des instructions, qui consiste à formuler le prompt système pour traiter certains contenus comme des données et ignorer les instructions qui s'y cachent. Ça aide contre les tentatives basiques, et c'est aussi la couche que les attaquants contournent le plus facilement en itérant. Considérez-la comme un simple ralentisseur. Rien de plus. Le filtrage des entrées et des sorties se situe un cran au-dessus : un classificateur qui repère un contenu ressemblant à une instruction, ou une sortie qui ressemble à une fuite. Il attrape les schémas connus et arrête les tentatives peu soignées. Un attaquant déterminé reformule, encode ou fractionne sa charge utile jusqu'à ce que quelque chose passe entre les mailles. Les deux couches qui changent vraiment l'issue quand les deux premières échouent : qui et quoi le modèle peut toucher, et comment vous traitez ce qui ressort à l'autre bout.

Couche de protectionCe qu'elle arrêteCe qu'elle laisse passer
Renforcement des entrées et du promptTentatives basiques, formulations connuesUne injection bien conçue ou indirecte
Accès à privilège minimal aux outils et aux donnéesLes dégâts une fois qu'une injection est passéeLa tentative d'injection elle-même
Gestion des sorties et supervision humaineUne réponse manipulée qui déclenche un dommage réelUn usage abusif à faible enjeu que personne n'a bloqué
Surveillance et journalisationLes tentatives répétées, repérées après coupLa première tentative réussie

Accès à privilège minimal aux outils et aux données

L'accès à privilège minimal est la défense qui continue de payer même quand toutes les autres couches échouent. Ne donnez au modèle, et à tout outil qu'il appelle, que les permissions et les données nécessaires à la tâche en cours. Un agent de support qui répond à des questions de facturation n'a pas besoin d'un accès en écriture à la base de données de facturation. Un outil de résumé de documents n'a pas besoin d'un outil capable d'envoyer des emails. Si une injection passe tous les filtres, le rayon des dégâts reste limité parce qu'aucun élément dangereux ne se trouve à portée. Définissez les clés API et les permissions des outils par tâche plutôt que par application. Séparez les identifiants utilisés par une fonctionnalité de résumé de ceux d'une fonctionnalité de facturation. Isolez les données par client pour que les documents de l'un ne puissent jamais répondre à la question d'un autre. Garder le rayon d'action du modèle étroit détermine si une injection finit un jour par vous coûter quelque chose.

Votre fonctionnalité LLM vient de devenir une surface d'attaque

Dès qu'un modèle lit du contenu externe ou détient un outil, le prompt injection cesse d'être une hypothèse. Envoyez-nous ce que vous avez construit, ce qu'il lit et ce qu'il est autorisé à toucher. Nous identifierons où une instruction injectée pourrait faire des dégâts et quels garde-fous combler en priorité.

Demander un audit de vos garde-fous

Gestion des sorties et supervision humaine

Tout ce qu'un modèle produit mérite la même méfiance que vous accorderiez à un texte tapé par un inconnu en ligne. Dans un sens bien réel, ça peut être exactement ça : les mots d'un inconnu, blanchis à travers votre modèle. Afficher cette sortie directement dans une page web sans l'échapper peut transformer une injection réussie en script stocké qui touche chaque visiteur après le premier. La faire passer dans une requête de base de données ou une commande shell transforme un problème de langage en problème d'exécution de code. La supervision humaine comble l'écart qu'aucun filtrage ne comblera jamais complètement. Tout ce qui a des conséquences, déplacer de l'argent, supprimer un enregistrement, envoyer un email à quelqu'un en dehors de votre entreprise, modifier une permission, devrait s'arrêter pour qu'une personne confirme d'abord, peu importe à quel point le modèle semble sûr de lui. Un modèle victime d'une injection réussie semble tout aussi sûr de lui qu'un modèle légitime. La confiance n'a jamais été le signal à croire.

Le filtrage des sorties attrape les schémas malveillants déjà connus dans ce que renvoie un modèle. Il n'attrapera pas une fuite subtile formulée d'une façon pour laquelle personne n'a encore écrit de règle. Considérez le filtrage comme un filet plein de trous, et placez une limite de permissions derrière tout ce qui compte vraiment.

Tester vos défenses

Tester les défenses contre le prompt injection ne ressemble pas à tester une fonctionnalité normale. Le résultat est une mesure de résistance, plus un gradient qu'une case à cocher. La seule méthode qui vaille est de faire du red teaming sur votre propre application, en tentant vous-même les attaques qu'un tiers essaierait avant que quelqu'un d'autre ne le fasse. Couvrez les deux angles. Essayez d'abord des tentatives directes via l'interface de chat, en demandant au modèle d'ignorer ses instructions ou de révéler son prompt système. Essayez ensuite des tentatives indirectes : glissez une instruction dans un document que votre application ingérerait normalement, et regardez si le modèle la suit. Un petit jeu de tests adversariaux attrape plus de failles qu'un jeu bien plus large de questions d'usage normal ne le fera jamais. Faites tourner ça avant le lancement, puis à nouveau chaque fois que le prompt système ou une source de données change, la même discipline que notre guide sur les métriques d'évaluation des LLM recommande pour les tests de non-régression. La personne qui a écrit la défense est généralement la pire placée pour la tester. Faites appel à un collègue pour qu'il passe vingt minutes à essayer de la casser.

Un socle de sécurité pour la phase MVP

Un fondateur qui doit avancer vite n'a pas besoin de garde-fous dignes d'une grande entreprise dès le premier jour. Un socle réaliste au stade MVP couvre quatre points :

  • Limitez chaque outil et chaque connexion de données aux permissions les plus étroites possible
  • Traitez par défaut tout contenu récupéré et toute sortie du modèle comme non fiable
  • Exigez qu'une personne confirme toute action à conséquences avant qu'elle ne s'exécute
  • Journalisez suffisamment d'activité pour qu'un schéma étrange soit repéré

Budgétez ça dès le départ. Le travail sur les garde-fous fait partie de la fonctionnalité elle-même. Le sauter finit par ressortir plus tard sous forme de ticket de support, ou pire. Notre guide sur le coût de développement d'une application IA chiffre ce que ça ajoute à un projet. La défense contre le prompt injection n'est qu'un élément d'un tableau de sécurité plus large. Notre guide sur la sécurité et la scalabilité dans le développement MVP couvre le reste. Aucune configuration ici ne rend une fonctionnalité LLM immunisée face à un attaquant déterminé. Un socle en couches, revu à mesure que la fonctionnalité grandit, oblige un attaquant réaliste à travailler plus dur que ce que le gain en vaut la peine. Si vous définissez les garde-fous d'une fonctionnalité qui touche à de vraies données utilisateur, parlez à notre équipe intégration IA et nous dimensionnerons la défense en conséquence.

Tags

Questions fréquentes

Trouve les réponses aux questions courantes sur ce sujet.