Ce qu’un relecteur humain examine réellement dans le code généré par l’IA
Une pull request générée par l’IA peut être ordonnée, lisible et accompagnée de tests au vert. Elle peut respecter le style du projet, mettre à jour la documentation, corriger des bugs visibles et finaliser une fonctionnalité en quelques heures. Le problème est que la sécurité ne s’évalue pas en vérifiant si le code compile ou si la démo fonctionne : il faut comprendre ce qui a réellement changé dans le comportement de l’application.
Une revue de code sécurisée (Secure Code Review) sur du code généré ou modifié par l’IA ne cherche pas des “erreurs d’IA” dans l’abstrait. Elle lit le diff au sein du produit : quelles données sont touchées, quelles routes sont exposées, quels rôles peuvent effectuer des actions, quelles requêtes sont modifiées, quels secrets entrent dans le périmètre, quelles dépendances ont été ajoutées, quels tests ont été modifiés et quelle configuration sera déployée en production.
Pour les développeurs, les CTO et les sociétés de services informatiques, le point critique est le suivant : le code généré par l’IA peut être plausible même lorsqu’il introduit une régression de sécurité. Une relecture humaine est nécessaire pour relier le code, la logique métier, les limites de confiance (trust boundaries), le déploiement et le risque réel avant que la fusion (merge) ne devienne une vulnérabilité en production.
Pourquoi une revue fonctionnelle ne suffit pas
La revue fonctionnelle vérifie si la fonctionnalité fait ce qui était demandé. La revue de code sécurisée demande également ce qui peut être détourné, quelles hypothèses ont changé et quels contrôles ont été affaiblis. Cette différence est cruciale lorsque le code est généré par l’IA, car l’assistant a tendance à optimiser l’exécution de la tâche, et non à préserver des limites de sécurité qui n’auraient pas été explicitées dans le prompt.
Un relecteur humain lit le code avec des questions différentes de celles d’une démo : que se passe-t-il si l’utilisateur change un ID, si le jeton est expiré, si le rôle est restreint, si le locataire (tenant) est différent, si le téléchargement contient un fichier inattendu, si une dépendance exécute des scripts, si une variable privée finit sur le frontend, ou si le pipeline saute un contrôle.
Les scanners aident, mais ne remplacent pas cette lecture. Le SAST, le scan de dépendances, le scan de secrets et le lint interceptent des modèles utiles, mais ne comprennent pas toujours la logique métier, l’isolation des locataires, les états du workflow, l’abus de fonctions légitimes, la sémantique des rôles ou l’impact d’un refactoring multi-fichiers.
Le premier contrôle : ce que la PR a réellement modifié
Les PR générées par l’IA peuvent être vastes : un prompt demande “ajoute cette fonctionnalité” et l’agent modifie des routes, des composants, des middlewares, des tests, des schémas de données, des dépendances, des configurations et la documentation. Le diff est cohérent, mais le relecteur doit séparer les fonctionnalités, le refactoring, les tests et les changements de sécurité.
La première activité consiste à classer les fichiers touchés. Les contrôleurs, routes API, actions serveur, middlewares, requêtes, migrations, politiques, fichiers .env.example, workflows CI/CD, Dockerfiles, gestionnaires de paquets, fichiers de verrouillage (lockfiles), politiques de stockage, configurations d’authentification et tests n’ont pas le même poids. Une petite modification dans un middleware ou les CORS peut être plus risquée que cent lignes d’interface utilisateur.
Lorsque le diff est trop volumineux, il doit être réduit ou découpé. Une revue efficace signifie être capable de dire : ce commit modifie la logique applicative, celui-ci modifie la présentation, celui-là les dépendances, et celui-ci le déploiement. Si tout est mélangé, le risque d’accepter une régression augmente.
Limites de confiance (Trust boundary) : là où le code ne peut plus être considéré comme sûr
Un relecteur humain recherche les limites de confiance. Le navigateur n’est pas fiable, le corps d’une requête n’est pas fiable, et il en va de même pour les en-têtes, les chaînes de requête, le stockage local, les rôles envoyés par le client, les fichiers téléchargés et la sortie d’un modèle. Même un service interne peut être moins fiable qu’il n’y paraît s’il reçoit des entrées d’utilisateurs ou d’intégrations externes.
Le code généré par l’IA peut franchir ces limites sans les marquer : il peut utiliser un user_id provenant du client au lieu de l’utilisateur en session, construire une requête avec des paramètres non validés, traiter une revendication de jeton comme une autorisation finale sans contrôle applicatif, ou transmettre la sortie d’un LLM vers du HTML, SQL, un shell, un ticket, un e-mail ou des outils en aval.
Lors de la revue, chaque limite de confiance doit soulever une question précise : qui contrôle cette donnée, où est-elle validée, où est-elle autorisée, où est-elle journalisée, que se passe-t-il si la valeur est manipulée ? Si la réponse n’est pas dans le code, le comportement n’est pas vérifiable.
Authentification, rôles et autorisations côté serveur
L’une des zones les plus importantes est le contrôle d’accès. Le relecteur vérifie si les nouvelles routes exigent une connexion, si elles vérifient le rôle, la propriété et le locataire, si elles appliquent le middleware correct et si elles ne délèguent pas les décisions de sécurité à l’interface utilisateur. Une application peut afficher les bons boutons mais avoir des API appelables directement.
La revue doit suivre les routes sensibles : lecture de données, modification, suppression, exportation, téléchargement, invitations, changement de rôle, fonctions d’administration, facturation, remboursements, approbations et usurpation d’identité. Pour chacune, le code doit répondre à qui peut l’appeler, sur quels objets, dans quel état et avec quelles limites.
Dans le code généré par l’IA, les modèles suspects les plus courants sont : if (user) sans contrôle de rôle, requête par ID sans vérification de propriété, tenant_id récupéré depuis le corps de la requête, isAdmin lu depuis le client, middleware non appliqué aux nouvelles routes, tests vérifiant uniquement l’utilisateur correct. Ces problèmes n’apparaissent souvent pas lors de la démo.
Logique métier et workflow hors séquence
La logique métier est l’une des raisons principales pour lesquelles une revue humaine est nécessaire. Un agent peut bien implémenter les étapes individuelles sans protéger la séquence : une invitation expirée peut être réutilisée, une commande peut être modifiée après le paiement, un remboursement peut être appelé par un rôle inapproprié, une demande peut être approuvée deux fois, une exportation peut inclure des données hors périmètre.
Le relecteur cherche des invariants : qu’est-ce qui doit toujours être vrai ? Une commande payée ne change pas de prix. Un document d’un locataire n’apparaît pas chez un autre. Un utilisateur suspendu ne génère pas de clé API. Un lien à usage unique ne peut pas être réutilisé. Un paiement ne peut pas être confirmé simplement parce que le frontend a affiché un succès.
La revue du code doit également lire les états, pas seulement les fonctions. Si le code modifie des statuts, rôles, paiements, quotas, limites, invitations ou autorisations, des contrôles d’état, l’idempotence et la gestion des cas négatifs sont nécessaires.
Requêtes, ORM et couche d’accès
De nombreuses vulnérabilités dans le code généré par l’IA ne se trouvent pas dans la syntaxe, mais dans la requête. Un ORM rend le code lisible, mais n’empêche pas les requêtes sans filtre de locataire, les jointures trop larges, les conditions manquantes ou les filtres appliqués après avoir récupéré les données. Une fonction peut charger tous les enregistrements et filtrer côté client ou côté application de manière incomplète.
Le relecteur vérifie où sont appliqués la propriété, le rôle et le locataire : dans la requête, dans la couche de service, dans la politique de base de données ou dans le contrôleur. Si le filtre est dupliqué dans de nombreuses routes, le risque qu’une nouvelle route générée par l’IA l’oublie augmente. Si la clé de service contourne les politiques et que le code ne filtre pas, la base de données devient exposée via le backend.
Les migrations et les seeds doivent également être lus : l’IA peut ajouter des colonnes sensibles, changer des valeurs par défaut, créer des index sur des données personnelles, rendre un champ critique nullable ou introduire des tables temporaires qui restent ensuite en production. Le modèle de données fait partie de la surface de sécurité.
Validation des entrées, gestion des sorties et téléchargements
Le code généré par l’IA gère souvent bien l’entrée prévue par le formulaire. La revue doit examiner les entrées imprévues : corps JSON manipulé, chaîne de requête, en-têtes, paramètres de chemin, téléchargement de fichiers, type MIME falsifié, nom de fichier, markdown, HTML, valeurs numériques hors plage, tableaux trop grands, objets imbriqués et charges utiles partielles.
La validation doit être côté serveur et cohérente avec la logique de domaine. Si une quantité doit être positive, si un rôle ne peut avoir que certaines valeurs, si un fichier doit être un PDF, si une date ne peut pas être dans le passé, ces contraintes ne peuvent pas vivre uniquement dans le formulaire frontend.
La sortie doit également être lue. HTML non échappé, messages d’erreur verbeux, traces de pile (stack traces), requêtes, chemins internes, jetons, détails de base de données et données d’autres utilisateurs peuvent sortir via des réponses, des logs, des exportations ou des modèles d’e-mail. Une revue sécurisée vérifie à la fois ce qui entre et ce qui sort.
Secrets, configurations et logs
Une revue de code sur du code généré par l’IA cherche des secrets dans des endroits ordinaires et moins ordinaires : sources, tests, .env.example, README, Dockerfile, workflows, scripts, logs, seeds, fixtures, configurations cloud, source maps et bundles frontend. L’IA peut copier une clé “temporaire” à un endroit qui finit par être déployé.
La revue ne se limite pas à dire “déplace-le dans env”. Elle vérifie si ce secret a déjà fuité, s’il doit être renouvelé, s’il est public ou privé, s’il a une portée minimale et s’il peut finir dans le client. Une clé de rôle de service, une URL de base de données ou un jeton cloud au mauvais endroit peuvent avoir un impact immédiat.
La journalisation (logging) et la gestion des erreurs sont d’autres zones sensibles. Lors du débogage, l’IA peut ajouter des logs très verbeux et les laisser dans le code : le relecteur vérifie qu’en production, aucune charge utile, jeton, requête, donnée personnelle (PII), chemin interne, trace de pile complète ou donnée client n’est imprimée.
Dépendances et chaîne d’approvisionnement dans le diff
Lorsque l’IA rencontre une erreur, elle propose souvent une bibliothèque. Cela peut être correct, mais chaque nouvelle dépendance entre dans la surface du produit. Paquets quasi homonymes, bibliothèques peu maintenues, licences incompatibles, scripts postinstall, dépendances transitives vulnérables et fichiers de verrouillage modifiés doivent être lus avec attention.
Le relecteur compare la nécessité réelle avec le coût de l’introduction du paquet : existe-t-il déjà une bibliothèque dans le projet, la dépendance est-elle maintenue, a-t-elle des CVE connues, exécute-t-elle des scripts, modifie-t-elle l’analyse, l’authentification, la cryptographie, le téléchargement, la désinfection, les modèles ou le réseau, le fichier de verrouillage montre-t-il plus de changements que prévu ?
Pour le code généré par l’IA, il est important de lire aussi ce qui est supprimé. Remplacer une bibliothèque peut éliminer des contrôles implicites, mettre à jour un framework peut changer des valeurs par défaut de sécurité, et déplacer une fonction dans un paquet “plus simple” peut entraîner la perte de validations déjà présentes.
Tests générés par l’IA : ce qu’ils confirment et ce qu’ils ne défient pas
Les tests écrits par l’IA tendent à confirmer le comportement implémenté. Ils sont utiles, mais couvrent souvent le chemin heureux (happy path) : entrée correcte, rôle correct, état correct, réponse prévue. Une revue de code sécurisée examine également le diff des tests pour comprendre s’ils ont été affaiblis.
Signaux à vérifier : tests supprimés, assertions moins précises, mocks trop permissifs, cas négatifs manquants, snapshots mis à jour sans explication, tests d’autorisation absents, erreurs gérées comme des succès, couverture qui augmente mais ne couvre pas les limites de confiance.
Pour chaque zone sensible, des tests négatifs sont nécessaires : mauvais utilisateur, mauvais locataire, jeton expiré, rôle restreint, entrée malveillante, fichier non valide, état hors séquence, demande dupliquée, limite dépassée. Si un bug de sécurité est trouvé, il doit devenir une régression dans le pipeline.
Configurations, CI/CD et déploiement
Une PR générée par l’IA peut également modifier ce qui envoie le code en production : Dockerfile, workflows CI/CD, variables d’environnement, CORS, en-têtes de sécurité, mode débogage, journalisation, IaC, permissions cloud, scripts de déploiement, protection de branche, portes de test. Ces fichiers ne sont pas des “accessoires”.
Le relecteur cherche des simplifications dangereuses : tests désactivés, SAST supprimé, scan de secrets contourné, débogage actif, CORS *, CSP affaiblie, jeton avec une portée plus large, déploiement automatique depuis une branche non protégée, logs trop verbeux, environnement de staging connecté à la production.
Si une modification de configuration est nécessaire, elle doit être explicite et proportionnée. Une build qui passe parce que les contrôles ont été désactivés n’est pas une version plus stable : c’est une version moins observable.
Prompts, fichiers de règles et instructions persistantes
Lorsque le projet utilise des règles Cursor, AGENTS.md, des instructions Claude, des prompts de projet ou des fichiers similaires, la revue doit les inclure s’ils influencent le code généré. Ces instructions peuvent orienter le style, les bibliothèques, les tests, la sécurité, le déploiement et les décisions de l’agent.
Un fichier de règles peut contenir des indications utiles, mais aussi des raccourcis dangereux : “désactive les contrôles en dev”, “utilise cette clé”, “ignore les tests instables (flaky)”, “ne demande pas de confirmation”, “utilise des politiques permissives”. Si l’agent suit ces instructions, le risque entre dans la PR même si le fichier ressemble à de la documentation.
Le relecteur vérifie si les instructions persistantes sont cohérentes avec le niveau de responsabilité du projet. Pour les équipes qui utilisent le codage par IA de manière continue, ces règles deviennent partie intégrante du processus de développement et méritent une appropriation explicite.
Comment lire une PR générée par l’IA trop volumineuse
Lorsqu’une PR générée par l’IA est trop large, le relecteur doit reconstruire une séquence que le diff ne raconte souvent pas bien. D’abord, on identifie le nouveau comportement : quelle fonctionnalité a été ajoutée, quel bug a été corrigé, quel flux a changé. Ensuite, on sépare les modifications de support : refactoring, déplacement de fichiers, renommage, mise à jour des tests, dépendances, configurations.
L’étape suivante consiste à isoler les zones à haute responsabilité. Même dans une PR énorme, certains fichiers pèsent plus que d’autres : middlewares, routes API, fournisseurs d’authentification, requêtes, migrations, gestion des secrets, fichiers de déploiement, workflows CI/CD, politiques de base de données, fonctions côté serveur et logique de paiement. La revue doit commencer par là, et non par les composants visuels les plus faciles à lire.
Si la PR modifie simultanément l’UI, l’API, la base de données et le déploiement, demander une séparation peut être une décision de sécurité. Ce n’est pas de la bureaucratie : cela sert à éviter qu’un changement sur les CORS, un nouveau paquet, une politique plus permissive ou une requête sans filtre de locataire ne restent cachés dans une fonctionnalité apparemment innocente.
Pour les sociétés de services informatiques, cette discipline est encore plus importante. Une PR générée par l’IA livrée au client doit pouvoir être expliquée : qu’est-ce qui a changé, quels fichiers ont été générés, quelles hypothèses ont été acceptées, quels tests démontrent que les limites sont restées correctes. Si l’on ne peut pas expliquer le diff, il est difficile d’en défendre la sécurité.
Ce qui doit ressortir de la revue : constatations et remédiation
Une revue de code utile ne produit pas seulement une liste de problèmes. Elle doit transformer le diff en décisions : ce qui bloque la fusion, ce qui doit être corrigé avant le déploiement, ce qui peut être planifié, quels tests doivent être ajoutés et quels risques restent acceptés avec un responsable. C’est particulièrement important avec du code généré par l’IA, car le même modèle peut se répéter dans les PR suivantes.
Les constatations doivent être décrites avec le contexte applicatif. “Contrôle d’autorisation manquant” est moins utile que “l’endpoint d’exportation utilise l’ID du locataire reçu du client et permet à un utilisateur authentifié d’exporter les données d’un autre espace de travail”. La seconde formulation permet aux développeurs, CTO et PM de comprendre l’impact, la priorité et la remédiation.
La remédiation doit privilégier les corrections structurelles. Si un endpoint manque d’isolation des locataires, corriger seulement cette route peut ne pas suffire : il pourrait être nécessaire d’ajouter un helper centralisé, une politique de base de données, un test négatif et une règle de revue pour les nouvelles routes. Si une dépendance a été ajoutée sans raison, le correctif peut être de la supprimer, de la remplacer par une bibliothèque déjà approuvée ou de bloquer les installations automatiques sans revue.
Le rapport final devrait indiquer au moins : périmètre révisé, fichiers et commits considérés, zones exclues, constatations bloquantes, constatations planifiables, tests suggérés, preuves de correctifs, risques résiduels et recommandations pour les prochaines PR IA. Cela rend la revue réutilisable, et non seulement corrective.
Quand une revue de code indépendante est nécessaire
Une revue interne peut suffire pour des modifications petites, isolées, sans données réelles, sans rôles, sans API exposées et avec des relecteurs experts sur les zones touchées. Une revue de code indépendante est nécessaire lorsque la PR générée par l’IA modifie l’authentification, les autorisations, les requêtes, la base de données, les secrets, les dépendances, le déploiement, la CI/CD, le cloud, les paiements, les téléchargements, les workflows ou la logique métier critique.
Elle est également nécessaire lorsque le diff est trop large pour être compris, lorsque l’équipe a accepté de nombreuses propositions “Tout accepter”, lorsque les scanners sont propres mais que le risque réside dans la logique applicative, ou lorsqu’une société de services doit livrer du code à un client et souhaite des preuves de contrôle avant la mise en production.
La revue de code ne ralentit pas la vitesse du codage par IA : elle évite que la vitesse ne déplace le coût après la mise en ligne. Une constatation corrigée avant la fusion coûte moins cher qu’une régression sur les données, les rôles ou le déploiement en production.
Comment ISGroup peut vérifier le code généré ou modifié par l’IA
ISGroup peut effectuer une revue de code ciblée sur les zones à haut risque du code généré par l’IA : diff, authentification, contrôle d’accès, logique métier, requêtes, secrets, journalisation, dépendances, configurations, tests et pipelines. Le périmètre peut être une PR unique, une fonctionnalité, un module, un dépôt ou un flux avant la mise en ligne.
| Si le code IA a modifié… | Risque principal | Contrôle conseillé |
|---|---|---|
| Auth, rôles, middleware, requêtes, API, logique métier, secrets ou dépendances | Vulnérabilités dans le code et régressions applicatives | Revue de code |
| Web app, API, téléchargements, exportations ou flux exposés en ligne | Comportements abusables de l’extérieur | Test de pénétration d’application web |
| CI/CD, politiques de revue, protection de branche, portes de test et usage continu d’agents | Contrôles non répétables sur les versions | Cycle de vie d’assurance logicielle |
| Cloud, IaC, IAM, buckets, base de données, env et déploiement | Mauvaise configuration ou privilèges excessifs | Évaluation de la sécurité cloud |
| Services, hôtes ou composants exposés avec versions et configurations connues | Vulnérabilités connues et surfaces techniques | Évaluation des vulnérabilités |
Le choix du contrôle dépend de ce qui a été touché. Pour le code généré par l’IA, la revue de code et le WAPT sont souvent complémentaires : la revue trouve la cause dans le code, le test applicatif démontre le comportement réel.
Vous avez une PR ou une fonctionnalité générée avec l’IA qui touche aux données, API, rôles, dépendances ou déploiement ? ISGroup peut effectuer une revue ciblée avant la fusion ou la mise en ligne.
Preuves à préparer
Préparez le dépôt, la branche, la PR, la description de la fonctionnalité, les prompts ou instructions pertinents, la liste des fichiers modifiés, les tests effectués, les parties générées par l’IA, les dépendances ajoutées, les configurations modifiées, les environnements impliqués et les risques déjà connus.
Pour une revue efficace, il faut aussi des données de contexte : rôles utilisateurs, limites de confiance, API exposées, schéma de données, fournisseur d’authentification, base de données, stockage, pipeline, variables d’environnement, services cloud et flux critiques. Le code ne parle pas de lui-même lorsque la vulnérabilité dépend du domaine.
Si la PR est large, il convient d’indiquer ce qui doit être considéré comme du refactoring et ce qui modifie le comportement. Si ce n’est pas clair, la première constatation peut être précisément le manque de séparation entre les modifications fonctionnelles et les modifications de sécurité.
Décision avant la fusion
Bloquez la fusion si la revue trouve un contrôle d’accès incomplet, des secrets exposés, des requêtes non filtrées, des clés de service dans le client, des tests de sécurité supprimés, des dépendances suspectes, du débogage en production, des CORS permissifs sans raison, une gestion des erreurs qui expose des données ou un pipeline affaibli.
Vous pouvez planifier après la fusion uniquement les améliorations avec un risque résiduel faible et un responsable clair : documentation, refactoring non urgent, augmentation progressive des tests, réduction de la duplication, amélioration du nommage. Les vulnérabilités qui exposent des données, rôles, paiements, cloud ou déploiements doivent être corrigées avant.
La décision doit produire des preuves : ce qui a été révisé, quelles constatations ont été corrigées, quels tests négatifs ont été ajoutés, quels risques subsistent et qui les possède.
Checklist pour la revue de code généré par l’IA
- Classez les fichiers et zones touchés par le diff.
- Séparez fonctionnalités, refactoring, tests, dépendances et configurations.
- Vérifiez l’authentification, les rôles, les locataires, les middlewares et les contrôles côté serveur.
- Lisez les requêtes, migrations, politiques et couche d’accès.
- Contrôlez la logique métier, les états, l’idempotence et les cas hors séquence.
- Vérifiez la validation des entrées, l’encodage des sorties, les téléchargements et la gestion des erreurs.
- Cherchez les secrets, logs verbeux, fichiers .env, chaînes de connexion et jetons.
- Révisez les dépendances, fichiers de verrouillage, scripts et nouveaux paquets.
- Contrôlez la CI/CD, CORS, en-têtes, Dockerfile, env, IaC et déploiement.
- Exigez des tests négatifs pour chaque zone sensible.
FAQ
- Si le SAST et les tests sont au vert, une revue de code est-elle encore nécessaire ?
- Oui. Les scanners et les tests interceptent des modèles et des chemins prévus, mais pas toujours la logique métier, les autorisations, les limites de confiance, les workflows et l’impact du diff sur le produit.
- Que regarde un relecteur humain que l’IA ne voit pas ?
- Le contexte applicatif : qui peut faire quoi, quelles données sont sensibles, quelles limites ne doivent pas être franchies, quelles hypothèses métier doivent rester vraies et quel risque arrive en production.
- Quelles PR IA sont les plus risquées ?
- Celles qui touchent à l’authentification, aux rôles, aux API, aux bases de données, aux secrets, aux dépendances, à la CI/CD, au cloud, aux paiements, aux téléchargements, aux exportations, à la journalisation ou aux configurations de déploiement.
- La revue de code remplace-t-elle le WAPT ?
- Non. La revue de code trouve des problèmes dans le code et la logique. Le WAPT vérifie le comportement réel de l’extérieur. Sur les applications exposées, les deux sont souvent nécessaires.
- Quand le cycle de vie d’assurance logicielle est-il nécessaire ?
- Lorsque le codage par IA est utilisé de manière stable par l’équipe et qu’il est nécessaire de rendre répétables les revues, tests, politiques, portes et contrôles sur chaque version.
- Puis-je faire réviser uniquement une fonctionnalité ?
- Oui, si le périmètre est clair : PR, module, flux, route ou composant. Pour les fonctionnalités qui touchent aux données et aux rôles, il est nécessaire d’inclure également les tests, configurations et dépendances liées.
[Callforaction-CR-Footer]
Sources et références utiles
- Guide de revue de code OWASP : https://owasp.org/www-project-code-review-guide/
- OWASP ASVS : https://owasp.org/www-project-application-security-verification-standard/
- OWASP Top 10 2021 : https://owasp.org/Top10/2021/
- OWASP Broken Access Control : https://owasp.org/Top10/en/A01_2021-Broken_Access_Control/
- OWASP Authorization Cheat Sheet : https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html
- OWASP Secrets Management Cheat Sheet : https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html
- OWASP SAMM : https://owasp.org/www-project-samm/
Leave a Reply