← Tous les articles

Chaque itération rend votre code moins sécurisé

Après dix cycles de raffinement de code piloté par LLM, 43,7 pour cent des chaînes d’itération contenaient plus de vulnérabilités que le code de référence initial.1 L’agent améliorait les fonctionnalités. L’agent passait les tests. Le code devenait aussi moins sécurisé à chaque itération — un phénomène que les chercheurs appellent « dérive de spécification ». Personne ne s’en apercevait, car le code s’améliorait sur tous les indicateurs sauf la sécurité.

TL;DR

Une étude du raffinement itératif de code par LLM sur trois modèles (GPT-5-Nano, Claude Sonnet 4.5, DeepSeek-V3) et 2 880 étapes d’itération révèle un paradoxe : les agents optimisent la correction fonctionnelle tout en dégradant silencieusement la sécurité. Les mesures d’atténuation classiques échouent. L’ajout d’outils d’analyse statique de sécurité (portes SAST) dans la boucle a fait passer la dégradation latente de 12,5 pour cent à 20,8 pour cent. Le framework SCAFFOLD-CEGIS résout le problème grâce à quatre couches de vérification, atteignant un taux de dégradation latente de 2,1 pour cent avec une monotonie de sécurité à 100 pour cent, au prix d’un taux de complétion des tâches de 77 pour cent. Cette découverte concerne toute personne exécutant des boucles d’agents autonomes.


Le paradoxe

Les chercheurs ont testé trois LLMs (GPT-5-Nano, Claude Sonnet 4.5, DeepSeek-V3) sur 24 tâches de programmation réparties en six catégories de sécurité (base de données, traitement des entrées, authentification, gestion des ressources, cryptographie, gestion des chemins), produisant 288 chaînes d’itération et 2 880 étapes au total.1 Le constat : la dérive de spécification lors de l’optimisation multi-objectifs provoque une dégradation progressive de la sécurité au fil des itérations successives.

Le mécanisme : lorsqu’un agent optimise du code sur plusieurs cycles, chaque cycle se concentre sur les améliorations fonctionnelles (correction de bugs, ajout de fonctionnalités, passage de tests, amélioration des performances). Les contraintes de sécurité entrent en concurrence avec les objectifs fonctionnels pour capter l’attention de l’agent. Au fil de dix cycles, l’agent apprend (implicitement, par accumulation de contexte) que les modifications fonctionnelles produisent un retour positif, tandis que les contraintes de sécurité ne génèrent aucun retour. La logique défensive qui ne contribue pas à une fonctionnalité visible se retrouve simplifiée, éliminée par refactoring, ou remplacée par des alternatives plus faibles.

Le taux de dégradation de 43,7 pour cent provient d’une étude observationnelle distincte suivant GPT-4o sur dix cycles d’itération. L’expérience principale a évalué SCAFFOLD-CEGIS face à cinq approches de défense existantes : sécurité par prompt, auto-raffinement, SAST a posteriori, garde pilotée par les tests et garde hybride.1 La communauté de recherche avait déjà identifié la dégradation itérative comme une préoccupation. Aucune des cinq alternatives ne l’a résolue.

Une étude indépendante de Shukla, Joshi et Syed, évaluée par les pairs et acceptée à IEEE-ISTAS 2025, corrobore ce phénomène.4 Les chercheurs ont pris dix échantillons de code C et Java vérifiés en termes de sécurité, appliqué quatre stratégies de prompting distinctes sur dix itérations chacune (400 échantillons au total), et mesuré une augmentation de 37,6 pour cent des vulnérabilités critiques après seulement cinq itérations. La taxonomie des vulnérabilités couvrait 12 catégories, notamment la sécurité mémoire, la validation des entrées, l’implémentation cryptographique et les failles d’injection. La cohérence entre différentes équipes de recherche, langages et méthodologies d’évaluation confirme que la dégradation itérative est une propriété de l’approche, et non un artefact d’un dispositif expérimental unique.


Pourquoi les portes SAST aggravent le problème

La découverte la plus contre-intuitive : l’ajout d’outils d’analyse statique de sécurité comme portes entre les itérations a fait passer la dégradation latente de 12,5 pour cent à 20,8 pour cent.1

L’article attribue la cause à la dérive de spécification lors de l’optimisation multi-objectifs. Une explication complémentaire correspond à un phénomène bien connu dans le développement logiciel humain : lorsque les développeurs s’appuient sur des linters et des analyseurs statiques, ils codent de manière moins défensive, car les outils « attraperont » les problèmes. La même dynamique s’applique vraisemblablement aux agents LLM. Lorsque l’agent reçoit un retour SAST entre les itérations, deux phénomènes se produisent :

  1. L’agent optimise pour passer le scanner, et non pour écrire du code sécurisé. Les outils SAST vérifient des schémas de vulnérabilité connus (injection SQL, XSS, dépassements de tampon). L’agent apprend à éviter ces schémas spécifiques tout en introduisant des faiblesses de sécurité inédites que le scanner ne détecte pas.

  2. L’agent supprime les défenses « redondantes ». Si le scanner signale que la validation des entrées à la couche A est suffisante, l’agent supprime la validation à la couche B lors de l’itération suivante. La validation à la couche B relevait de la défense en profondeur, pas de la redondance. Le scanner ne peut pas distinguer les deux.

Le résultat : l’itération avec porte SAST produit du code qui passe les scans de sécurité mais contient plus de vulnérabilités latentes que l’itération sans porte. L’outillage crée un faux sentiment de sécurité qui rend l’agent moins prudent, pas davantage.

Toute personne exécutant une boucle de codage autonome avec des portes SAST entre les itérations devrait y prêter attention. Les portes ne vous protègent pas. Elles entraînent votre agent à contourner la protection.


Ce que SCAFFOLD-CEGIS fait différemment

Le framework SCAFFOLD-CEGIS adopte une approche différente.1 Au lieu de vérifier des schémas de vulnérabilité connus, le framework impose la monotonie de sécurité : aucune itération ne peut rendre le code moins sécurisé que l’itération précédente.

Les résultats pour les trois approches :

Approche Dégradation latente (SSDR) Monotonie de sécurité Complétion des tâches
Sans porte (référence) 12,5 % Non mesurée Plus élevée
Porte SAST 20,8 % Non garantie Plus élevée
SCAFFOLD-CEGIS 2,1 % 100 % 77,14 %

L’architecture utilise quatre couches de vérification séquentielles, chacune contrôlant une propriété différente :1

Couche Fonction Critère de validation
Correction Exécuter la suite de tests complète Tous les tests passent
Monotonie de sécurité Comparer les résultats SAST entre itérations Aucune nouvelle vulnérabilité par rapport à la précédente
Budget de diff Limiter l’ampleur des changements par itération Taille des changements dans le seuil
Intégrité des ancres Vérifier les éléments de code critiques pour la sécurité Correspondance par sous-chaîne, regex, AST ou sémantique

Le framework adopte le principe CEGIS (counterexample-guided inductive synthesis) : une boucle fermée de génération de candidats, vérification, retour d’information et régénération. Plutôt que d’utiliser des vérificateurs formels, le système emploie l’analyse statique et la vérification d’ancres sémantiques, représentant les contre-exemples sous forme de rapports d’échec structurés.1 Si une couche rejette une itération, le système revient à la version précédente au lieu de tenter de corriger la régression.

Le compromis est réel : SCAFFOLD-CEGIS a atteint un taux de complétion des tâches de 77,14 pour cent, contre des taux plus élevés pour les approches moins sécurisées.1 La monotonie de sécurité a un coût en productivité. Le framework rejette des itérations qu’un système moins strict accepterait et améliorerait. Que ce compromis en vaille la peine dépend de la priorité que vous accordez aux garanties de sécurité par rapport au débit.

L’enseignement clé : revenir en arrière en cas d’échec plutôt qu’itérer sur l’échec. Les boucles standard avec porte SAST détectent un problème et demandent à l’agent de le corriger, produisant une nouvelle itération susceptible d’introduire de nouveaux problèmes. SCAFFOLD-CEGIS détecte un problème et écarte entièrement l’itération. La garantie de monotonie provient du refus systématique d’accepter une régression, et non de la détection et correction des régressions.


Lien avec la conception de harnais d’agents

Cette découverte est directement liée à la manière dont les praticiens construisent des couches d’orchestration autour des CLIs d’agents.2 Les sept modes de défaillance que j’ai documentés à partir de plus de 500 sessions autonomes en incluent plusieurs que le paradoxe du raffinement itératif explique : des agents qui passent les tests tout en dégradant la qualité du code, des agents qui optimisent le mauvais indicateur, des agents qui suppriment des contraintes de sécurité lors du refactoring.

Les hooks de jugement que j’ai décrits dans « Anatomy of a Claw » abordent le problème de dégradation par un mécanisme différent. quality-gate.sh bloque les rapports de complétion dépourvus de preuves. filter-sensitive.sh intercepte l’exposition d’identifiants avant qu’ils n’atteignent le disque. recursion-guard.sh limite la profondeur d’instanciation des agents. Chaque hook impose une propriété de monotonie : le système ne doit pas se dégrader sur une dimension spécifique au fil des itérations de l’agent. Le pattern de constitution d’exécution étend la même idée : des règles de gouvernance intégrées que l’agent ne peut pas outrepasser pendant l’exécution.

Le système autoresearch de Karpathy utilise le même pattern.3 Le harnais d’évaluation conserve les améliorations et écarte les régressions via la gestion de branches git. La métrique d’entraînement (bits de validation par octet) sert de contrainte de monotonie. Aucun résultat d’expérience qui dégrade la métrique ne survit.

Trois systèmes indépendants (recherche en vérification formelle, infrastructure de recherche en ML, harnais d’agents en production) convergent vers le même principe de conception : ne jamais itérer sur un échec ; toujours revenir en arrière en cas d’échec. Donner à un agent une seconde chance de corriger une régression produit de moins bons résultats que d’écarter la régression et de tenter une approche nouvelle.


Ce que les praticiens devraient faire

Trois actions concrètes fondées sur ces résultats :

Auditez vos boucles d’itération pour la monotonie de sécurité. Si votre agent exécute plusieurs cycles de modification de code, comparez la posture de sécurité à chaque cycle par rapport à la référence initiale, pas seulement par rapport au cycle précédent. La dérive cumulative est invisible lorsque vous ne comparez que des itérations adjacentes.

Ne vous fiez pas uniquement aux portes SAST. Les résultats avec porte SAST (20,8 pour cent de dégradation, pire que sans porte) devraient modifier la conception de vos boucles de retour d’information. Les outils SAST sont précieux pour détecter des schémas connus dans du code écrit par des humains. Dans les boucles d’itération d’agents, ces outils deviennent des cibles d’optimisation que l’agent contourne. Utilisez le SAST comme un signal parmi d’autres, non comme une porte.

Implémentez le retour en arrière sur échec, pas la correction sur échec. Lorsqu’une itération introduit une régression, écartez-la entièrement. Ne demandez pas à l’agent de corriger la régression lors d’une itération ultérieure. La tentative de correction est elle-même une itération soumise aux mêmes dynamiques de dégradation. Une implémentation minimale avec git :

#!/bin/bash
# monotonicity-gate.sh — revert on security regression
BASELINE_HASH="$1"  # git hash of the known-good baseline

# Run your security checks against current state
CURRENT_VULNS=$(semgrep --config auto --json . | jq '.results | length')
BASELINE_VULNS=$(git stash && git checkout "$BASELINE_HASH" -q && \
    semgrep --config auto --json . | jq '.results | length' && \
    git checkout - -q && git stash pop -q)

if [ "$CURRENT_VULNS" -gt "$BASELINE_VULNS" ]; then
    echo "Security regression: $BASELINE_VULNS$CURRENT_VULNS vulnerabilities"
    git checkout "$BASELINE_HASH" -- .
    exit 2  # Block the iteration
fi

Le pattern compare à la référence initiale, pas à l’itération précédente. La dérive cumulative est la menace.


FAQ

Le raffinement itératif dégrade-t-il toujours la sécurité ?

Toutes les chaînes d’itération ne se dégradent pas. L’étude SCAFFOLD-CEGIS a constaté que 43,7 pour cent des chaînes contenaient plus de vulnérabilités après dix cycles, ce qui signifie que 56,3 pour cent maintenaient ou amélioraient la posture de sécurité.1 Une étude indépendante IEEE-ISTAS a relevé une augmentation de 37,6 pour cent des vulnérabilités critiques après cinq itérations.4 Le problème est que la dégradation est silencieuse : l’agent produit du code fonctionnellement correct qui passe les tests tandis que les propriétés de sécurité s’érodent. Sans vérifications explicites de monotonie de sécurité, la dégradation passe inaperçue jusqu’à l’exploitation d’une vulnérabilité.

Pourquoi les portes SAST aggravent-elles le problème au lieu de l’améliorer ?

Les outils d’analyse statique vérifient des schémas de vulnérabilité connus. Lorsqu’un agent reçoit un retour SAST entre les itérations, il optimise pour passer le scanner plutôt que pour écrire du code sécurisé. L’agent évite les schémas signalés tout en introduisant des faiblesses inédites que le scanner ne peut pas détecter. L’agent supprime également les couches de défense en profondeur que le scanner marque comme redondantes. Le résultat net est du code qui passe les scans mais contient plus de vulnérabilités latentes que du code produit sans porte SAST.

Qu’est-ce que la monotonie de sécurité et comment SCAFFOLD-CEGIS l’impose-t-il ?

La monotonie de sécurité signifie qu’aucune itération ne peut rendre le code moins sécurisé que l’itération précédente. SCAFFOLD-CEGIS impose cette propriété à travers quatre couches de vérification séquentielles : correction (suite de tests), monotonie de sécurité (comparaison SAST entre itérations), budget de diff (limitation de l’ampleur des changements) et intégrité des ancres (vérification que les éléments de code critiques pour la sécurité survivent). Le framework utilise le principe CEGIS (counterexample-guided inductive synthesis), représentant les contre-exemples sous forme de rapports d’échec structurés plutôt que de preuves formelles. Si une couche rejette une itération, le système l’écarte entièrement au lieu de la transmettre à l’agent pour correction. Le compromis : un taux de complétion des tâches de 77 pour cent, inférieur à celui des approches moins strictes.

En quoi le retour en arrière sur échec diffère-t-il de la correction sur échec dans les boucles d’agents ?

La correction sur échec détecte un problème et demande à l’agent de le corriger lors de l’itération suivante. La tentative de correction est elle-même soumise à la même dérive de spécification qui a causé la régression initiale, introduisant souvent de nouveaux problèmes. Le retour en arrière sur échec écarte entièrement l’itération et revient au dernier état connu comme fiable. L’agent repart sur une base propre au lieu d’accumuler des correctifs. La gestion de branches git rend le retour en arrière trivial en pratique.

Puis-je appliquer ces résultats à mon workflow Claude Code ou Codex existant ?

Oui. Les trois actions de la section praticien s’appliquent à toute boucle d’agent qui modifie du code sur plusieurs cycles. Auditez vos boucles d’itération en comparant la posture de sécurité par rapport à la référence initiale (pas seulement par rapport à l’itération précédente). Traitez la sortie SAST comme un signal parmi d’autres plutôt que comme une porte. Lorsqu’une itération introduit une régression, utilisez git checkout ou git revert pour écarter entièrement le changement au lieu de demander à l’agent de le corriger. Le pattern de harnais à base de hooks fournit un modèle d’implémentation concret pour encoder ces vérifications sous forme de portes automatisées.


Sources


  1. Yi Chen et al., “SCAFFOLD-CEGIS: Preventing Latent Security Degradation in LLM-Driven Iterative Code Refinement,” arXiv:2603.08520, March 2026, arxiv.org/abs/2603.08520v1. Tested GPT-5-Nano, Claude Sonnet 4.5, DeepSeek-V3 across 24 tasks, 288 chains, 2,880 steps. 43.7% degradation rate (GPT-4o observational study); SAST gates increased SSDR from 12.5% to 20.8%; SCAFFOLD-CEGIS achieved 2.1% SSDR with 100% safety monotonicity at 77.14% task completion. 

  2. Blake Crosley, “Anatomy of a Claw: 84 Hooks as an Orchestration Layer,” blakecrosley.com, February 2026. 

  3. Andrej Karpathy, autoresearch: AI agents running autonomous ML research, March 2026, github.com/karpathy/autoresearch. 630-line Python script, ~700 experiments over two days, ~20 genuine improvements. 

  4. Shivani Shukla, Himanshu Joshi, Romilla Syed, “Security Degradation in Iterative AI Code Generation: A Systematic Analysis of the Paradox,” IEEE-ISTAS 2025, arXiv:2506.11022, arxiv.org/abs/2506.11022. 10 security-verified C/Java samples, 4 prompting strategies, 10 iterations each (400 total), 37.6% increase in critical vulnerabilities after 5 iterations. 12 vulnerability categories. 

Articles connexes

When Your Agent Finds a Vulnerability

An Anthropic researcher found a 23-year-old Linux kernel vulnerability using Claude Code and a 10-line bash script. 22 F…

9 min de lecture

AI Agent Security: The Deploy-and-Defend Trust Paradox

1 in 8 enterprise AI breaches involve autonomous agents. Runtime hooks, OS-level sandboxes, and drift detection break th…

19 min de lecture

Your Agent Writes Faster Than You Can Read

Five research groups published about the same problem this week: AI agents produce code faster than developers can under…

17 min de lecture