Aller au contenu

Guide

Checklist pratique pour relire le code généré par IA avant de le merger

Dix points à vérifier dans le code écrit par un assistant : dépendances inventées, contrôles d’accès côté navigateur, erreurs avalées, tests qui n’assertent rien.

· 9 min de lecture · Par l’équipe vetkit

Un robot présente fièrement une fenêtre de code pendant qu’une développeuse coche les éléments d’une grande checklist sur un porte-bloc.Un robot présente fièrement une fenêtre de code pendant qu’une développeuse coche les éléments d’une grande checklist sur un porte-bloc.

Le code produit par un assistant compile généralement, se lit bien et fait à peu près ce que vous avez demandé. C’est précisément pour cela qu’on le valide si facilement. Les erreurs sont rarement des fautes de syntaxe. Ce sont des décisions que le modèle a prises en silence : une dépendance dont il a supposé l’existence, un contrôle de permission placé au mauvais endroit, une erreur qu’il a décidé d’ignorer.

Voici la checklist que nous utilisons pour relire les modifications écrites avec l’aide de l’IA. Il ne s’agit pas de juger l’élégance du code, mais de traquer la poignée de problèmes qui finissent en incidents.

Pourquoi le code IA demande une autre revue

Quand un collègue écrit du code, vous pouvez généralement faire confiance aux parties qu’il n’a pas mentionnées. Il connaissait la base de code, a testé la modification en local et vous aurait prévenu si quelque chose était inachevé. Un modèle n’a rien de ce contexte, sauf si vous le lui avez fourni, et il a tendance à combler les trous avec quelque chose de plausible plutôt qu’avec une question. La revue passe donc de « est-ce bien écrit ? » à « qu’a-t-il supposé ? ».

1. Dépendances

Vérifiez chaque paquet ajouté par la modification. Existe-t-il sur le registre ? Est-ce le paquet recommandé par la documentation officielle, ou un paquet au nom ressemblant ? A-t-il été publié la semaine dernière ? Les modèles inventent parfois des noms de paquets, et certains de ces noms sont ensuite enregistrés par des attaquants. Notre guide sur le slopsquatting explique comment vérifier un paquet en une minute.

Regardez aussi les versions. Une version épinglée sur un numéro jamais publié cassera la prochaine installation à partir de zéro, et une dépendance non épinglée signifie que le code que vous avez relu n’est pas celui qui s’exécute.

2. Secrets et variables publiques

Cherchez dans le diff les clés, jetons et mots de passe, y compris dans les fichiers de test et les exemples. Examinez ensuite les variables d’environnement avec des préfixes publics comme VITE_, NEXT_PUBLIC_ ou EXPO_PUBLIC_. Tout ce qui porte ces préfixes est copié dans le bundle du navigateur au moment du build. Un assistant peut renommer un secret avec l’un de ces préfixes pour faire fonctionner une fonctionnalité dans le navigateur. Ce guide détaille cette erreur dans le cas d’une clé d’API de LLM.

3. Où l’accès est contrôlé

Trouvez la ligne qui décide si l’utilisateur courant a le droit de faire cette action. Si elle se trouve dans un composant React, un garde de route ou un bouton masqué, c’est une fonctionnalité d’expérience utilisateur, pas de la sécurité. N’importe qui peut appeler votre API directement. Le contrôle doit avoir lieu côté serveur, à chaque requête, sur la ressource consultée : pas seulement « cet utilisateur est-il connecté ? » mais « cette facture appartient-elle à cet utilisateur ? ».

Méfiez-vous des nouvelles routes d’API sans aucun middleware d’authentification, et des backends comme Supabase ou Firebase où la base de données est accessible depuis le navigateur. Là, la protection repose sur les règles propres à la base. Une table Supabase sans row level security est ouverte à quiconque possède votre clé anon publique.

4. Entrées non fiables

Suivez la saisie utilisateur depuis son point d’entrée jusqu’à son point d’utilisation. Le SQL construit par concaténation de chaînes, les commandes shell assemblées à partir de champs de requête, les chemins de fichiers issus de paramètres de requête, le HTML rendu à partir de contenu utilisateur et les URL récupérées pour le compte d’un utilisateur sont les schémas classiques d’injection, de path traversal, de XSS et de SSRF. Les assistants en produisent encore, surtout quand le code environnant fait déjà quelque chose de similaire.

text
// Looks harmless, is an injectiondb.query(`SELECT * FROM users WHERE email = '${req.query.email}'`); // Parameterizeddb.query('SELECT * FROM users WHERE email = $1', [req.query.email]);

5. Code inachevé

Les longues générations s’arrêtent parfois avant la fin. Cherchez dans la modification les marques provisoires : TODO, « implement later », « rest of the code here », des fonctions qui renvoient des données d’exemple codées en dur, des identifiants factices, et des fichiers aux noms comme utils copy.ts. Cherchez aussi les suppressions d’avertissements globales comme // @ts-ignore, un eslint-disable en tête de fichier, ou un any utilisé pour faire taire le vérificateur de types. Elles cachent souvent le problème exact que le modèle n’a pas su résoudre.

6. Gestion des erreurs

Un bloc catch qui journalise et continue, ou qui attrape tout et renvoie un résultat vide, transforme un échec bruyant en perte de données silencieuse. Demandez-vous ce qui doit se passer quand cet appel échoue, et si le code le fait. Méfiez-vous des tentatives répétées sans limite et des erreurs converties en réponses de succès.

7. Tests

Les tests générés méritent d’être lus ligne par ligne. Problèmes fréquents : des tests qui n’assertent jamais rien, des tests qui mockent la fonction même qu’ils testent, des assertions qui vérifient seulement qu’une fonction a été appelée, et des .only ou .skip oubliés. Une suite de tests qui passe ne prouve rien tant que vous ne savez pas qu’elle peut échouer. Cassez volontairement le code une fois et voyez si un test s’en aperçoit.

8. Timeouts et appels bloquants

Les appels HTTP sortants sans timeout sont un incident de production qui n’attend qu’une dépendance lente. Beaucoup de clients populaires attendent indéfiniment par défaut, dont requests en Python et http.DefaultClient en Go. En Node.js, des opérations de fichiers synchrones ou un hachage de mot de passe dans un gestionnaire de requête bloquent toutes les autres requêtes de ce processus. Ces problèmes apparaissent rarement lors des tests en local, car votre portable et vos dépendances sont rapides et peu sollicités.

9. Accès aux données

Repérez les requêtes dans des boucles (le problème N+1), les endpoints de liste qui renvoient toutes les lignes sans pagination, et les clients de base de données créés à chaque requête au lieu d’être partagés. Examinez aussi les migrations avec soin : une synchronisation de schéma lancée au démarrage, ou une migration qui supprime puis recrée une table, peut effacer des données de production au prochain déploiement.

10. Fonctionnalités LLM

Si la modification appelle un modèle, traitez sa sortie comme une entrée non fiable. Elle ne doit jamais être exécutée, concaténée dans du SQL ni rendue en HTML brut. Vérifiez que la clé d’API reste sur le serveur, que la route qui appelle le modèle exige un utilisateur connecté et applique une limite de débit, et que la longueur de la sortie est plafonnée. Si un agent dispose d’outils, vérifiez ce que ces outils peuvent faire et si du texte provenant de documents ou de pages web peut les piloter.

En faire une routine

Dix vérifications par pull request, c’est beaucoup à faire à la main, et l’intérêt d’une checklist est justement de ne plus compter sur sa mémoire. La plupart de ces points peuvent être automatisés, au moins en partie. Votre attention reste ainsi disponible pour ce que les outils font mal, comme savoir si la modification répond réellement au besoin du produit.

vetkit regroupe ces contrôles en suites : sécurité (secrets, dépendances vulnérables, vulnérabilités du code, configuration de l’infrastructure), qualité du code, maintenabilité, risques du code IA (paquets inventés, code inachevé, pièges des plateformes d’applications, sécurité des LLM et des agents) et préparation à la production (timeouts, appels bloquants, usage de la base de données, fondamentaux opérationnels). Il lit votre code sans l’installer, le builder ni l’exécuter, et signale ce qu’il trouve avec le fichier, la ligne et une suggestion de correction. Comme toute analyse statique, il peut passer à côté de certaines choses et se tromper : il appuie une revue, il ne la remplace pas.

Demander un accès anticipé

Parlez-nous de votre équipe et des dépôts que vous souhaitez auditer. Nous ouvrons l’accès par petits groupes et vous répondrons par e-mail.

Nous utilisons ces informations uniquement pour répondre à votre demande. Politique de confidentialité