Rapport de pentest : prouver la correction des failles
Un rapport de pentest ne prouve pas qu’une faille est corrigée. Découvrez les preuves à conserver et la méthode pour préparer un dossier vérifiable.

Après un pentest, comment prouver que les failles sont vraiment corrigées ?
Un rapport de test d'intrusion décrit des vulnérabilités. Il ne suffit pas, à lui seul, à prouver qu'elles ont été corrigées. Pourtant, c'est souvent ce rapport - parfois avec quelques captures d'écran - qu'on ressort quand un auditeur, un client grand compte ou une équipe sécurité demande des preuves.
Le problème est concret : entre la découverte d'une faille et sa clôture, il faut décider de son périmètre, modifier le code, faire relire le changement et vérifier qu'il n'a pas introduit un autre défaut. Si ces étapes ne sont pas reliées, l'organisation peut avoir corrigé une partie du problème sans pouvoir le démontrer clairement. Et, pire : conclure qu'une faille est « résolue » parce qu'elle n'apparaît plus dans un export.
La bonne réponse n'est pas un document plus épais. C'est une chaîne de preuves lisible, où chaque constat mène à une décision, à une modification identifiable et à un contrôle après correction. Voici les éléments à conserver, les erreurs fréquentes et une méthode concrète illustrée par un exercice réalisé sur OWASP NodeGoat.
Pourquoi le rapport de pentest ne suffit pas
Un rapport de pentest répond d'abord à une question : qu'est-ce qui ne va pas dans le périmètre testé ? Il répertorie les vulnérabilités, leur niveau de risque, les conditions d'exploitation et, souvent, des recommandations. Utile pour démarrer, mais ce n'est pas un dossier de clôture.
Ensuite, l'auditeur ou le client veut savoir autre chose : qu'est-ce qui a été identifié, ce que l'équipe a décidé de faire, quelle modification a été réalisée et comment on a vérifié le résultat. Une liste de tickets marqués « terminé » répond à un statut, pas forcément à une preuve.
Dans les projets réels, l'information se disperse vite. Le rapport est dans un espace documentaire, les tickets dans un outil de suivi, les changements dans Git et les résultats de scan ailleurs. Quelques mois plus tard, celui ou celle qui prépare l'audit doit encore retrouver le commit, comprendre la décision et montrer que le constat traité correspond bien à celui du rapport initial.
Le sujet n'est donc pas uniquement la sécurité du code. C'est la traçabilité de la remédiation. Une chaîne claire permet d'éviter les ambiguïtés : corrigé, risque accepté, hors périmètre, ou encore à traiter.
Cette distinction compte aussi dans les relations avec des entreprises clientes et dans des audits liés à des exigences de sécurité ou au RGPD. Le RGPD ne prescrit pas un format universel de « preuve de pentest » : les demandes varient selon le contexte, les contrats et le référentiel appliqué. Donc, avant de figer un modèle, il vaut mieux vérifier ce que l'auditeur ou le client attend. L'objectif reste le même : fournir des éléments vérifiables, plutôt que demander au lecteur de faire confiance à une déclaration.
Un rapport décrit les constats. Le dossier de remédiation relie chaque constat à une décision, un changement et un contrôle.
Une approche pratique consiste à traiter chaque constat comme une unité de travail traçable. On commence par établir la liste des vulnérabilités concernées, puis on associe à chacune une preuve de correction (ou une justification documentée). Cette logique évite deux pièges : élargir le périmètre en cours de route sans accord, ou faire « disparaître » un constat sans expliquer ce qu'il devient.
Pour cadrer la classification d'une faiblesse, on peut relier le constat à une référence stable comme CWE-601, la redirection vers une URL non fiable. Une référence CWE aide à comprendre de quoi on parle, mais elle ne remplace ni le contexte applicatif ni les preuves de correction.
Les preuves à conserver pour chaque vulnérabilité
Pour chaque ligne du rapport, le dossier doit permettre à quelqu'un qui n'a pas participé aux travaux de reconstituer ce qui s'est passé. Une feuille de calcul suffit souvent comme point d'entrée, à condition qu'elle pointe vers les pièces justificatives et qu'elle ne prétende pas remplacer ces pièces.
Voici les six éléments à relier à chaque constat.
1. Un identifiant stable et une description précise
Conservez l'identifiant du rapport d'origine, le type de faiblesse et son emplacement dans le code : dépôt, fichier et ligne si ces informations restent pertinentes. Par exemple : « F-004 - redirection ouverte - CWE-601 - app/routes/index.js, ligne 72 » est plus utile que « problème de redirection ».
Attention : la ligne de code peut changer après modification. Ce qui reste essentiel, c'est l'identifiant stable, pour retrouver le constat dans le rapport et dans les échanges. Conservez donc les références initiales et ajoutez, si besoin, l'emplacement mis à jour, sans réécrire l'historique.
2. La preuve du périmètre accepté
Avant de commencer, écrivez noir sur blanc quels constats l'équipe s'engage à traiter dans cette campagne. C'est le périmètre convenu. Il protège contre deux dérives : ajouter des travaux sans discussion, ou retirer discrètement une vulnérabilité difficile à corriger.
Un constat non inclus n'est pas forcément « sans importance ». Il est simplement hors du périmètre de l'exercice. La feuille doit permettre de le distinguer d'une faille corrigée ou d'un risque accepté. Si le périmètre change, enregistrez la décision, la date et la personne qui valide.
3. Le changement associé
Reliez chaque faiblesse à une modification identifiable : idéalement une demande de fusion (pull request) dédiée. La description doit expliquer ce qui a changé et pourquoi, en faisant référence à l'identifiant du constat.
Une correction isolée se relit plus facilement qu'un gros lot de modifications sans découpage. Et ça évite des ambiguïtés : si plusieurs failles sont corrigées dans la même demande, le réviseur doit pouvoir comprendre quelle partie répond à quel constat, et si les changements sont indépendants.
4. L'auteur et la revue interne
Indiquez qui a préparé le changement et qui, côté équipe responsable du dépôt, l'a examiné puis fusionné. Ce n'est pas là pour « distribuer des blâmes ». C'est pour montrer que le changement a suivi le processus prévu, et qu'il n'a pas été appliqué sans contrôle.
La revue reste importante même si la correction vient d'un outil automatique ou d'un prestataire. C'est l'équipe qui maintient le produit qui garde la responsabilité du code et de la mise en production.
5. Le résultat du contrôle après correction
Conservez le résultat d'un nouveau scan après fusion, ou après application de la correction dans le périmètre effectivement contrôlé. L'objectif est simple : montrer que le constat initial n'est plus détecté, et signaler si d'autres problèmes sont apparus.
Un scan « propre » ne prouve pas, à lui seul, que l'application est exempte de vulnérabilités. Il répond plutôt à une question limitée : le contrôle réalisé (avec ses règles et son périmètre) retrouve-t-il le problème ciblé ? Les tests du projet et la CI restent nécessaires pour vérifier le comportement du code et éviter une régression.
6. La date de clôture
Ajoutez la date de fusion et, si elle est différente, celle du contrôle de vérification. Ces dates permettent de situer la correction par rapport à l'audit et d'expliquer le statut d'un constat à un moment donné.
Au minimum, un tableau peut contenir : identifiant, faiblesse, emplacement, statut et justification, lien vers la modification, auteur, approbateur, résultat du scan, date. Les détails peuvent rester dans les demandes de fusion et dans les rapports de scan ; le tableau sert surtout à retrouver rapidement les bons éléments.
La règle est simple : une ligne par constat, des liens vers les preuves, et un statut qui ne cache pas les exceptions. Cette structure est généralement plus exploitable qu'un long texte où les décisions sont difficiles à repérer.
Un exemple concret : le cas OWASP NodeGoat
L'exercice décrit dans le dossier source a été réalisé le 14 octobre 2026 sur OWASP NodeJS Goaten, une application Node.js volontairement vulnérable. Seize constats avaient été inclus dans le périmètre. Quinze ont été corrigés au moyen de cinq demandes de fusion : six corrections basées sur des règles de Railo et neuf rédigées manuellement par un ingénieur. Le dernier constat a été expliqué, mais pas modifié.
Une ligne du dossier d'évidence présente le constat F-004 de cette manière :
- Identifiant : F-004
- Faiblesse : redirection ouverte, CWE-601
- Emplacement :
app/routes/index.js, ligne 72 - Correction : Railo
- Vérification : constat absent au nouveau scan, aucun nouveau constat signalé
- Demande de fusion : 1
- Fusion : 14 octobre 2026
Cette ligne ne raconte pas toute l'histoire, mais elle permet de la retrouver. La demande de fusion précise la modification et son intention ; le rapport de contrôle documente le nouveau scan. Un lecteur peut passer du constat à la correction sans devoir reconstituer tout le parcours à partir de messages éparpillés.
Le cas non corrigé est, justement, plus instructif. F-007 concernait une clé privée TLS présente dans le dépôt. Supprimer le fichier de la version courante ne suffit pas : la clé peut rester accessible dans l'historique Git et doit donc être considérée comme exposée. Le dossier indique « expliqué, non modifié » et consigne les actions recommandées : émettre une nouvelle clé et un nouveau certificat, conserver les secrets hors du dépôt, supprimer le fichier et réécrire l'historique si le dépôt est ou a été public.
Réécrire l'historique n'est pas une opération anodine. Des clones et des copies peuvent déjà exister ; la stratégie doit prendre en compte les utilisateurs du dépôt et la rotation des secrets. L'action essentielle reste de remplacer la clé compromise, puis de gérer l'historique selon le niveau d'exposition et les contraintes du projet. Effacer un fichier sans révoquer ni remplacer le secret ne neutralise pas le risque.
Après fusion des changements, le scan final n'a retrouvé que ce constat. Le dossier ne présente donc pas artificiellement un résultat « tout corrigé » : il montre quinze corrections et une exception expliquée. C'est plus crédible, et plus utile, pour une revue, qu'un statut global vert qui masquerait la réalité.
Le dossier complet et son fichier CSV sont annoncés à l'adresse railo.dev/sample-evidence. Comme pour tout exemple public, il faut l'adapter aux exigences du client, au processus interne et aux règles de conservation applicables. Le format reste un point de départ, pas une norme universelle.
Éviter les fausses clôtures et organiser la remédiation
Trois erreurs reviennent souvent, parce qu'elles donnent l'impression d'avancer vite. En pratique, elles fragilisent la preuve et rendent la correction plus difficile à auditer.
Faire disparaître la preuve au lieu de corriger la faiblesse
Supprimer un fichier, une ligne du rapport ou une règle du scanner peut faire disparaître un constat d'un export. Ça ne veut pas dire que la vulnérabilité a été éliminée. Le dossier doit montrer une modification qui supprime réellement la faiblesse, puis un contrôle qui confirme le résultat dans un périmètre explicite.
Si un constat est erroné ou ne s'applique pas à l'environnement concerné, documentez cette décision et expliquez le raisonnement. « Non applicable » ou « risque accepté » sont des statuts possibles, mais il faut les justifier et les valider par les bonnes personnes. Modifier les données du scan pour obtenir une liste plus « propre » n'est pas de la remédiation.
Fusionner sans vérifier le résultat
Une correction peut supprimer une vulnérabilité et en introduire une autre. Elle peut aussi ne pas couvrir tous les chemins concernés. Le nouveau scan apporte une vérification ; les tests du projet, la revue de code et la CI couvrent d'autres angles.
Ces contrôles ne sont pas interchangeables. Le scan ne garantit pas que le correctif fonctionne dans tous les cas ; la CI ne prouve pas forcément que la faiblesse initiale a disparu. Il faut donc conserver des éléments adaptés à chaque question et éviter de présenter un résultat limité comme une garantie générale de sécurité.
Regrouper trop de corrections dans une seule demande
Une demande de fusion unique avec des dizaines de changements est difficile à relire et à rattacher précisément aux constats d'origine. En général, une demande par faiblesse améliore la traçabilité et rend la revue plus précise. Mais ce n'est pas une loi : des corrections étroitement liées peuvent parfois être regroupées si la relation entre chaque constat et le changement est clairement documentée.
Le critère utile est simple : arrive-t-on à répondre clairement à deux questions ? Quelle modification traite quelle faiblesse ? Qui a vérifié ? Si un regroupement rend ces réponses opaques, séparez.
Un déroulé opérationnel plutôt qu'une collection de documents
Une campagne de correction peut s'organiser en cinq étapes :
- Importer les constats depuis le rapport de pentest, un export de scanner ou un questionnaire client, en conservant leurs identifiants d'origine.
- Valider le périmètre par écrit, avec les responsables et les exceptions connues.
- Associer chaque constat à une correction traçable, avec une demande de fusion dont la description explique le changement.
- Faire relire et fusionner par l'équipe qui possède le code, puis lancer les tests et le contrôle de sécurité après correction.
- Assembler le dossier de preuve, en reliant chaque ligne aux demandes de fusion, aux revues et aux résultats de vérification.
Dans l'offre Fix Sprint décrite par Railo, les constats sont transmis et le périmètre est convenu avant le travail. L'équipe annonce livrer, en une semaine, une demande de fusion par faiblesse : certaines corrections reposent sur des règles, d'autres sont rédigées manuellement et examinées en fonction du code où elles s'insèrent. Chaque correction est rescannée ; l'équipe cliente conserve la revue et la fusion, puis reçoit un dossier de preuves.
La source indique un tarif fixe de 1 500 dollars pour un dépôt. Elle précise aussi que rien n'est fusionné sans revue du client et que le code du dépôt n'est pas exécuté de leur côté. Ces conditions sont propres à cette offre : à vérifier avec le prestataire. Elles ne valent pas recommandation générale ni garantie de résultat pour tous les projets.
Le modèle a un intérêt opérationnel : il transforme une liste de constats en changements relisibles et en preuves associées. Ses limites doivent aussi rester visibles. Une correction automatique ne remplace pas une revue compétente ; un délai d'une semaine dépend de la taille du périmètre et de la complexité des failles ; et la validation finale appartient à l'organisation qui exploite le logiciel.
Pour préparer votre propre processus, commencez par un tableau de suivi et un modèle de demande de fusion. Définissez les statuts autorisés, les responsables de validation et la forme du contrôle après correction. Ensuite, faites valider ce format par l'auditeur ou le client concerné, avant d'avoir à produire le dossier dans l'urgence.
Conclusion : une preuve utile vaut mieux qu'un statut « corrigé »
Un rapport de pentest identifie des problèmes ; il ne clôt pas le travail. Pour chaque constat, conservez un identifiant, une décision sur le périmètre, un changement explicable, une revue, un contrôle après correction et une date. Si une faille reste ouverte, indiquez-le et documentez la raison et la suite prévue.
Prochaine étape : prenez votre dernier rapport et vérifiez si chaque constat peut être relié à une décision et à une preuve. Sinon, construisez le tableau avant le prochain audit - pas la veille. Et confirmez toujours les attentes précises du client ou de l'auditeur : le « bon » dossier est celui qui permet de vérifier ce qui a réellement été fait.