Ce que c'est et pourquoi ça compte
Quand Claude Code termine un travail et vous dit « fait, tests passés », on a l'impression que l'histoire est finie. Elle ne l'est pas. Des tests au vert vous disent une seule chose : le code fait ce que les tests vérifient. Et les tests vérifient ce qui a été demandé. Si vous avez demandé « permets-moi d'enregistrer une commande », le test vérifie que la commande est enregistrée. Personne n'a demandé ce qui se passe si quelqu'un l'enregistre sans être connecté, ou au nom d'un autre utilisateur.
C'est pour ça que « il passe les tests » ne veut pas dire « il est sûr ». Une app peut passer tous ses tests et, en même temps, laisser un utilisateur lire les données d'un autre, accepter deux fois le même paiement ou laisser une clé secrète dans la partie qui tourne dans le navigateur, où n'importe qui peut la lire.
C'est aussi ce que dit une étude parue sur arXiv le 10 octobre 2026, « Last Secure Code Benchmark: Is the Code You Vibe Secure? ». Elle a testé six des agents de programmation les plus avancés. Leur code passe les tests de fonctionnement dans 73,6 à 91,3 % des tâches, selon l'agent. Mais même le meilleur des six n'écrit du code à la fois fonctionnel et sûr que dans 25,1 % des tâches.
Demander à la même session de revérifier ne sert pas à grand-chose : elle vient d'écrire ce code et sait pourquoi elle l'a fait comme ça. Ce que je fais, moi, c'est ouvrir une deuxième session et lui donner un rôle précis, celui d'attaquant. Elle ne sait rien de la façon dont le code est né, elle ne voit que les modifications et elle a une tâche : trouver comment les casser. Je ne lui demande pas si le code est bon. Je lui demande où il cède.
Pourquoi ça compte : si vous construisez une app sans être développeur, vous ne verrez pas ces trous en relisant le code. Et si personne ne les cherche, le premier à les trouver sera un utilisateur.
1. Le prompt de l'attaquant
Je le colle tel quel dans la deuxième session, quand la première a fini et que les tests sont au vert.
Tu es un attaquant, pas un relecteur gentil. Ce code passe les tests : ça m'est égal, les tests vérifient seulement ce qui a été demandé. Tu n'as qu'une tâche : trouve comment casser ce qui vient d'être fait. Regarde seulement les modifications : lance git status et git diff HEAD (il montre aussi celles déjà indexées), et lis en entier les nouveaux fichiers que git status liste (le diff ne les montre pas). Cherche : - qui peut l'appeler : ce qui se passe sans connexion, connecté avec le compte d'un autre utilisateur, en appelant l'adresse directement ; - données incorrectes : champs vides, textes très longs, caractères bizarres, nombres négatifs, mauvais types, la même requête envoyée deux fois ; - clés en clair : mots de passe, tokens ou clés secrètes écrits dans le code, dans les logs, dans les messages d'erreur ou dans la partie qui tourne dans le navigateur ; - permissions : qui peut lire, modifier ou supprimer des données qui ne sont pas les siennes ; - cas limites : listes vides, réseau lent, deux utilisateurs au même moment. Pour chaque problème, écris : où (fichier et ligne), comment je le casse (les étapes exactes), ce qui se passe, gravité (haute, moyenne, basse). Trie du plus grave au moins grave. Ne corrige rien et ne modifie pas les fichiers : je veux seulement le rapport.
Pourquoi il est écrit comme ça, ligne par ligne.
- « Tu es un attaquant, pas un relecteur gentil » : un relecteur gentil essaie de comprendre le code et, à la fin, a tendance à le valider. Un attaquant part de l'idée qu'il y a un trou et va le chercher.
- « Lance git status et git diff HEAD » : git diff tout court ne montre que les modifications pas encore indexées (en stage), c'est-à-dire pas encore marquées avec git add pour le prochain commit. git diff HEAD les compare toutes avec le dernier commit, marquées ou non. Les fichiers que git ne suit pas encore n'y apparaissent toujours pas : git status les liste, et c'est pour ça que le relecteur les lit en entier.
- « Qui peut l'appeler » : une page peut cacher un bouton à ceux qui n'ont pas la permission, mais si l'adresse que ce bouton appelle répond à n'importe qui, le bouton caché ne protège rien. C'est pour ça que le prompt demande d'appeler l'adresse directement.
- « Comment je le casse (les étapes exactes) » : avec les étapes, vous pouvez vérifier vous-même si le problème existe vraiment et, après la correction, les refaire pour voir s'il a disparu. Un « il pourrait y avoir un risque », vous ne pouvez pas le vérifier.
- « Ne corrige rien et ne modifie pas les fichiers » : celui qui attaque signale, c'est tout. Les corrections, c'est la session qui a écrit le code qui les fait, comme ça vous savez toujours qui a changé quoi.
2. Comment je l'utilise
- La première session dit « fait, tests passés ». Je ne lui demande pas de se revérifier.
- J'ouvre un nouveau terminal dans le même dossier et je lance claude : une nouvelle session, qui n'a pas vu la conversation.
- Je colle le prompt avant le commit, pour que git status et git diff HEAD ne montrent que le travail qui vient d'être fait. Si j'ai déjà fait le commit, je lui indique moi-même les fichiers.
- J'apporte le rapport à la première session et je fais corriger en commençant par la gravité haute. Pour chaque problème sérieux, je demande aussi un test qui le reproduit, comme ça la prochaine fois c'est le test qui le vérifie.
Du rapport aux corrections
Je transmets le rapport à la première session avec ce prompt :
Voici le rapport d'une autre session qui a essayé de casser ton travail : [colle le rapport]. Commence par les problèmes de gravité haute, un par un. Pour chacun, écris d'abord un test qui le reproduit et vérifie qu'il échoue, puis corrige et vérifie que le test passe. Dis-moi ce que tu as changé et comment tu l'as vérifié. Ne touche pas aux gravités basses : c'est moi qui décide.
Le test qui échoue avant la correction, c'est le morceau qui compte. Il vous dit que le problème existait vraiment et que ce n'était pas une idée du relecteur. Et il reste dans le projet : si une modification future rouvre le même trou, ce test passe au rouge.
Si vous voulez être sûr qu'il ne touche à rien
Le prompt dit de ne pas modifier les fichiers, mais ça reste une demande. Si je veux un vrai blocage, j'ouvre la deuxième session en plan mode :
claude --permission-mode plan
En plan mode, Claude lit les fichiers et lance des commandes pour explorer, comme git status et git diff HEAD, mais il ne modifie pas le code tant que vous n'approuvez pas un plan. Si à la fin il vous en propose un avec des corrections, ne l'approuvez pas : le rapport suffit. Dans une session déjà ouverte, vous y passez en appuyant sur Shift+Tab jusqu'à ce que « plan mode on » apparaisse en bas.
3. N'expliquez rien
Je n'explique pas au relecteur pourquoi le code est fait comme ça. Si vous le lui expliquez, il finit par vous donner raison.
Ça vaut pour chaque phrase que vous ajoutez au prompt : « je l'ai fait comme ça parce que… », « cette partie est provisoire », « la connexion est déjà gérée par une autre partie de l'app ». Ce sont des phrases qui mettent le relecteur de votre côté avant même qu'il regarde le code. Donnez-lui les modifications et la tâche, rien de plus. Les explications vous servent après, quand vous décidez quoi corriger.
Les erreurs les plus courantes
- Lire « tests passés » comme « sûr » : les tests vérifient ce qui a été demandé, donc quand vous touchez à la connexion, aux permissions ou aux données, faites toujours un tour avec l'attaquant.
- Demander à la même session d'attaquer son propre code : ouvrez un nouveau terminal et lancez claude, pour que celui qui attaque ne soit pas celui qui l'a écrit.
- Le lancer après le commit sans dire quels fichiers : git diff HEAD ne montre plus le travail qui vient d'être fait, donc indiquez-lui vous-même les fichiers à regarder.
- Expliquer à l'attaquant pourquoi le code est fait comme ça : donnez-lui seulement les modifications et la tâche, sinon il finit par vous donner raison.
- Corriger sans test : pour chaque problème sérieux, faites d'abord écrire un test qui le reproduit, comme ça s'il revient vous le verrez.
- Corriger tout ce qu'il trouve : commencez par la gravité haute et décidez vous-même pour les basses, sinon le code se remplit de protections inutiles.
Check-list
- Les tests sont au vert et la première session a fini
- L'attaquant est dans une nouvelle session
- Aucune explication ajoutée au prompt
- Avant le commit, ou avec les fichiers indiqués
- Chaque problème a le fichier et la ligne, les étapes, l'effet et la gravité
- Chaque problème de gravité haute est corrigé et a son test
Questions fréquentes
Si les tests ne suffisent pas, à quoi servent-ils ?
Ils servent, et beaucoup. Ils vous disent que ce que vous avez demandé fonctionne et que la prochaine modification ne le cassera pas sans que vous le remarquiez. Ils ne vous disent pas ce qui se passe quand quelqu'un utilise l'app d'une façon que personne n'avait demandée. Les deux travaillent ensemble : l'attaquant trouve le trou, le test le garde fermé.
Il n'y a pas une commande toute prête pour la sécurité ?
Si. /security-review analyse les modifications de votre branche à la recherche de vulnérabilités de sécurité : il les compare avec la branche principale du dépôt distant, donc il faut que le projet en ait un, sur GitHub par exemple. /code-review, lui, cherche des bugs dans les modifications en cours. Le prompt, en revanche, couvre aussi des choses qui ne sont pas que de la sécurité, comme les données incorrectes et les cas limites, et vous donne les étapes pour reproduire chaque problème.
Quand est-ce que ça vaut la peine ?
Quand la modification touche à la connexion, aux permissions, aux données des utilisateurs ou aux paiements, ou ajoute une adresse que l'app appelle depuis le navigateur. C'est là qu'un trou retombe sur ceux qui utilisent l'app. Pour un texte ou une couleur, ce n'est pas utile.