
Plan de remédiation : structurer la correction après un audit ou
un pentest
Un plan de remédiation construit sur un vrai export de findings : 14 lignes, 80 findings couverts, un chemin d'attaque "prouvé" qu'il a fallu revérifier, et l'ordre expliqué.
Maxime J8 min de lectureMis à jour le
Un rapport plein de findings ?
On vous aide à trier ce qui compte et à bâtir un plan de remédiation tenable.
Prioriser vos correctifsUn plan de remédiation prend une liste de findings, issue d'un audit, d'un pentest ou d'un scan, et attache à chacun une priorité, un responsable, un délai et un mode de vérification. La liste décrit le risque ; le plan décide de ce qu'on en fait, dans quel ordre, et comment on saura que c'est refermé.
Plutôt qu'un modèle vide, voici un plan construit sur un vrai export : celui de notre plateforme EASM, avec son module de pentest, sur son compte de démonstration. Le tri qui précède, c'est-à-dire comment 28 findings "critiques" se réduisent à quatre constats prouvés, est détaillé dans le guide de la gestion des vulnérabilités. Ici, on part du résultat de ce tri pour écrire le plan.
Le jeu de données, et ses limites
Le plan, ligne par ligne
Quatorze lignes couvrent 80 des 616 findings : les 28 critiques, plus les élevés et moyens qui partagent une cause avec eux, et ceux dont la preuve enregistrée tient déjà seule, comme le .git/ de BrokenCrystals ou l'injection CRLF de ginandjuice.shop. D'autres élevés passent d'abord par une confirmation (un indice d'XXE sur rest.vulnweb.com, par exemple, n'est encore qu'un écho de requête) ; le reste, en grande majorité faible ou informatif, relève de l'hygiène et se traite par lots au cycle courant. La colonne à lire en premier est la quatrième : la sévérité après tri s'écarte de la sévérité annoncée sur sept lignes sur quatorze.
| Finding | Actif | Annoncé | Après tri | Responsable | Action | Délai |
|---|---|---|---|---|---|---|
| Chaîne de connexion à la base dans le JavaScript client | brokencrystals.com | Critique | Critique | Dev front + admin BD | Révoquer l'identifiant, le remplacer, déplacer l'appel côté serveur | 24 h |
| config.json servi publiquement, identifiants BD dont un bloc production (2 findings, 1 fichier) | brokencrystals.com | Critique | Critique | Exploitation web + admin BD | Retirer de la racine web, changer les mots de passe exposés | 24 h |
| db.sql servi publiquement (2 findings, 1 fichier) | rest.vulnweb.com | Critique | Critique | Exploitation web | Retirer, interdire .sql côté serveur, évaluer ce que contient le dump | 24 h |
| /.svn/wc.db (SQLite de 1 004 Ko vérifié) et /.git/ exposés (5 findings) | brokencrystals.com | Élevée | Critique | Exploitation web + dev | Bloquer /.svn/ et /.git/, chercher des secrets dans l'historique récupérable | 24 h |
| Injection SQL et pivot vers rest.vulnweb.com, chemin marqué "prouvé" par l'outil | testasp.vulnweb.com | Absent de la liste | À confirmer | Pentester | Rejouer l'injection et le pivot ; ticket de correction seulement si l'un tient | 72 h |
| phpinfo() exposé via info.php (8 findings, 1 fichier) | rest.vulnweb.com | Élevée | Moyenne | Exploitation web | Supprimer le fichier | 72 h |
| XSS DOM par pollution de prototype, confirmée (lot de 4 findings) | ginandjuice.shop | Élevée | Élevée | Dev front | Bloquer __proto__ et constructor dans les fusions d'objets, textContent au lieu de href dynamique | 7 jours |
| Injection CRLF dans le paramètre category, en-tête injecté renvoyé | ginandjuice.shop | Élevée | Élevée | Dev backend | Refuser CR et LF avant toute écriture d'en-tête, rejouer la même requête | 7 jours |
| .env Laravel exposé, sans secret (APP_KEY et DB_PASSWORD vides) | brokencrystals.com | Critique | Faible | Exploitation web | Retirer, dans le même changement que config.json | Avec la ligne 2 |
| Apache 2.4.25 et PHP 7.1.26 en fin de vie (5 findings) | rest.vulnweb.com | Élevée | Élevée | Exploitation système | Planifier la migration ; CVE HTTP/2 déduites de la bannière, à confirmer | 30 jours |
| IIS 8.5 : 10 CVE déduites de la bannière, dont 3 critiques | testasp.vulnweb.com | Critique | À confirmer | Exploitation système | Écarter CVE-2021-31166 (hors périmètre), relever la version de Windows, planifier la sortie de Server 2012 R2 | 30 jours |
| En-tête Content-Security-Policy absent (7 findings, 4 hôtes) | 4 hôtes | Moyenne | Moyenne | Dev front | CSP en mode report-only, puis bloquante ; priorité à ginandjuice.shop | 30 jours |
| Fichiers Terraform, CI/CD et flux de debug "exposés" (23 findings) | preview.owasp-juice.shop, brokencrystals.com | Critique ou élevée | Faux positif | Équipe qui exploite l'outil | Clore avec la preuve (la réponse est la page HTML de l'application), signaler la règle | Immédiat |
| Findings dérivés : KEV/EPSS, conformité, chaînes, corrélations (11) | ginandjuice.shop (10), preview.owasp-juice.shop (1) | Critique | Pas de ticket | Aucun | Suivre les findings sources, déjà présents dans le plan | Sans objet |
Pourquoi cet ordre
Les secrets d'abord, et la révocation avant le correctif. Les quatre lignes à 24 h ont un point commun : n'importe qui peut lire le fichier, sans compte ni interaction, et une fois lu, le retirer ne sert plus à rien. Retirer le config.json ferme la fuite ; seul le changement des mots de passe annule ce qui a déjà fuité. C'est aussi pourquoi aucune de ces lignes ne relève d'un patch : ce sont des erreurs de déploiement, qu'une mise à jour ne corrige pas.
Un chemin d'attaque "prouvé" par l'outil reste une affirmation à vérifier. L'outil a calculé trois chemins, et n'en marque qu'un comme prouvé :
Sur le papier, ce chemin ferait monter tout ce qu'il traverse. Nous l'avons donc vérifié avant de lui confier l'ordre du plan, et il ne tient pas en l'état. Le pivot repose sur un hébergement partagé, or testasp.vulnweb.com résout vers 44.238.29.244 et répond en IIS 8.5 sur Windows Server, quand rest.vulnweb.com résout vers 18.215.71.186 et répond en Apache 2.4.25 sur Debian, avec PHP 7.1.26 : ni adresse ni pile en commun. La "preuve" enregistrée pour ce lien se résume à une phrase de synthèse, sans requête, et aucun finding d'injection SQL sur testasp ne figure dans l'export. La ligne 5 existe donc pour rejouer l'injection et le pivot, pas pour corriger : un ticket de correction ne s'ouvrira que si l'un des deux se confirme. Le db.sql reste à 24 h sans l'aide de ce chemin, pour la raison donnée plus haut : n'importe qui peut le télécharger. Les deux autres chemins sont marqués inférés, et l'un d'eux passe par le /.svn/wc.db de BrokenCrystals, que nous avons remonté en critique sur sa propre preuve. La leçon vaut pour tout outil : un libellé "prouvé" posé automatiquement se vérifie comme n'importe quel autre constat avant de décider des priorités.
Une faille confirmée n'est pas forcément la plus urgente. La XSS DOM est le seul constat du lot rejoué dans un navigateur, et elle passe pourtant après les fichiers exposés : elle demande qu'une victime suive un lien piégé, là où le config.json se lit d'une requête. Sept jours, pas vingt-quatre heures. La CSP de la ligne 12 commence par ginandjuice.shop pour la même raison : sur cet hôte, elle réduit l'impact d'une XSS déjà prouvée.
L'effort compte. Le info.php ne vaut qu'une sévérité moyenne après tri, c'est une fuite d'informations de configuration, mais sa correction consiste à supprimer un fichier. Il passe à 72 h devant des chantiers plus graves et plus longs, comme la sortie d'un serveur en fin de support. Pourquoi le score de gravité seul ne tranche pas ces arbitrages est développé dans le guide de la gestion des vulnérabilités.
Une ligne par cause, pas par finding
Les 80 findings tiennent en quatorze lignes parce que le plan suit les causes. Un seul info.php produit huit findings, parce que cinq détecteurs le voient et que le même service est inventorié sous deux noms d'actif. Une seule bannière IIS produit dix CVE. Et trois lignes (config.json, .env, chaîne de connexion) partagent la même cause racine : des artefacts de développement qui partent en production. Les corriger un par un ferme la fuite ; ajouter à la chaîne de build un contrôle qui refuse ces fichiers empêche la suivante. Quand une cause est diffuse dans le code, un pentest avec accès au code source en retrouve toutes les occurrences, là où un test externe n'en voit que celles qui répondent sur une URL.
Assigner, dater, vérifier
La colonne responsable nomme un type d'équipe parce que l'organisation est fictive ; dans un vrai plan, elle porte un nom de personne. Les délais s'alignent sur vos fenêtres de maintenance et votre capacité de retour arrière, ce que détaille l'article sur le patch management. Deux lignes du tableau sont d'ailleurs des candidates naturelles à une acceptation de risque temporaire, documentée et datée : les deux serveurs en fin de vie, le temps que la migration se fasse.
La vérification est la condition de clôture, et l'export montre pourquoi. Sur les 39 findings passés "corrigés", une partie vient d'une réconciliation automatique : un scan postérieur n'a pas reproduit le constat, ce qui ne prouve pas qu'il a disparu. Le db.sql est ainsi marqué corrigé sur un actif et ouvert sur l'autre, alors que c'est le même fichier. Un ticket ne se ferme qu'après avoir rejoué la preuve d'origine : la même requête sur le même chemin, et pour la ligne 5, l'injection puis le pivot annoncés par l'outil. C'est pour cela que le retest fait partie d'un pentest bien mené et qu'il pèse dans le prix d'un test d'intrusion.
Un plan de remédiation se refait à chaque rapport. Branché sur une découverte continue des actifs, comme le fait l'EASM, il part à chaque fois d'un périmètre à jour. Si vous avez un rapport en attente et besoin d'aide pour le trier et en tirer un plan tenable, la page contact est le plus court chemin.
Questions fréquentes sur le plan de remédiation
Qui rédige le plan de remédiation, le prestataire ou le client ?
Les deux, chacun sa part. Le prestataire qui a fait l'audit ou le pentest propose le tri, la sévérité après vérification et l'action technique, parce qu'il a la preuve en main. Le client fixe les responsables et les délais, parce qu'il connaît ses fenêtres de maintenance, ses dépendances et ses équipes. Un plan dont les dates ont été posées par quelqu'un qui ne connaît pas le système ne sera pas tenu.
Un tableur suffit-il pour tenir un plan de remédiation ?
Pour un rapport de quelques dizaines de lignes, oui : les sept colonnes du tableau de cet article tiennent dans n'importe quel tableur, avec une colonne d'état et une date de retest. Un outil de ticketing devient utile quand plusieurs équipes corrigent en parallèle ou quand les findings arrivent en continu, ce qui est le cas avec une surveillance de surface d'attaque.
Peut-on décider de ne pas corriger une vulnérabilité ?
Oui, quand le coût est disproportionné ou l'exposition quasi nulle. La décision doit alors être écrite, datée, motivée et signée par quelqu'un qui a l'autorité de l'assumer, avec une date de réexamen. Sans cette trace, une acceptation de risque ne se distingue pas d'un oubli, ni pour un auditeur ni après un incident.
Veille sécurité
La suite, une fois par mois
Ce qui bouge vraiment sur la surface d'attaque externe, NIS2 et la sécurité applicative, écrit par le pentester qui signe ces articles. Un envoi par mois, désinscription en un clic.
Votre adresse ne sert qu'à cet envoi. Voir la politique de confidentialité.