Audit de code PHP : évaluer et sécuriser une application vieillissante

· 17 min de lecture · Par Godefroy de Compreignac, CEO
Points clés
  • Un audit de code PHP passe en revue le code source d’une application existante pour mesurer ses risques : versions de PHP et des dépendances, configuration, authentification, contrôle des accès, traitement des données saisies et tests
  • PHP 8.1 ne reçoit plus de correctifs de sécurité depuis le 31 décembre 2025, PHP 7 depuis novembre 2022 et PHP 5 depuis fin 2018. PHP 8.2 en recevra jusqu’au 31 décembre 2026
  • Classez chaque faille selon son exposition, l’impact d’une exploitation, la facilité à l’exploiter et le coût du correctif. Une faille joignable sans compte et facile à exploiter se corrige dans la semaine
  • Un audit donne un état des lieux à une date donnée. C’est un diagnostic avec un plan d’action, sans valeur de certification

Un audit de code PHP passe en revue le code source d’une application existante pour mesurer ses risques de sécurité et sa dette technique : versions de PHP et des dépendances, configuration du serveur, authentification, contrôle des accès, traitement des données saisies et tests. Il se termine par une liste de correctifs classés par priorité et par une recommandation entre correction progressive et refonte. Sur une application de plus de cinq ans, le premier constat est souvent le plus simple : la version de PHP installée ne reçoit plus de correctifs de sécurité.

Ce guide s’adresse aux PME, aux ETI et aux éditeurs logiciel qui ont une application PHP en production et qui envisagent un audit après une alerte : un bulletin de vulnérabilité sur une dépendance, un message de l’hébergeur, une question d’un client sur la sécurité. Il détaille les signes d’une application à risque, le périmètre de l’audit, les failles PHP les plus fréquentes dans un code ancien, la façon de prioriser les correctifs, le choix entre correction et refonte, et les actions à lancer dès cette semaine.

Les signes d’une application PHP à risque

L’équipe de PHP maintient aujourd’hui chaque branche du langage pendant quatre ans : deux ans de support actif, puis deux ans de correctifs de sécurité seuls. Une fois ce délai passé, l’équipe de PHP ne corrige plus aucune faille découverte dans le langage.

Branche PHPFin des correctifs de sécuritéÉtat au 22 octobre 2026
5.631 décembre 2018Sans correctifs
7.428 novembre 2022Sans correctifs
8.026 novembre 2023Sans correctifs
8.131 décembre 2025Sans correctifs
8.231 décembre 2026Correctifs de sécurité jusqu’à la fin de l’année
8.331 décembre 2027Correctifs de sécurité seulement
8.431 décembre 2028Support actif
8.531 décembre 2029Support actif

Source : calendrier des versions publié sur php.net.

Beaucoup d’applications sont concernées. Selon W3Techs, au 22 octobre 2026, 26,9 % des sites écrits en PHP tournent encore en PHP 7 et 7,7 % en PHP 5. PHP 7 ne reçoit plus de correctifs depuis novembre 2022, PHP 5 depuis fin 2018. Certaines distributions Linux à support long, comme Red Hat Enterprise Linux, continuent cependant de corriger les failles de la version de PHP qu’elles fournissent. Vérifiez d’où vient le PHP de votre serveur avant de conclure.

Fin des correctifs de sécurité par version de PHP, de PHP 5.6 en 2018 à PHP 8.5 en 2029

Au-delà de la version du langage, d’autres signes reviennent souvent dans les applications PHP écrites il y a plus de cinq ans :

  • le framework a lui-même dépassé sa fin de support (une ancienne version de Symfony ou de Laravel, CodeIgniter 3 ou Zend Framework, remplacé depuis par Laminas)
  • des bibliothèques ont été copiées à la main dans le dépôt au lieu d’être installées avec Composer, donc personne ne les met à jour
  • le code utilise encore les fonctions mysql_*, supprimées en PHP 7.0, ou construit ses requêtes SQL en collant des chaînes de caractères
  • les mots de passe sont stockés en MD5 ou en SHA-1 au lieu de password_hash(), disponible depuis PHP 5.5
  • l’application n’a aucun test automatisé et se déploie par FTP
  • une seule personne connaît le code, ou plus personne depuis le départ du prestataire

Ces signes ne prouvent pas qu’une faille existe. Ils montrent en revanche qu’une faille, si elle existait, resterait sans doute longtemps ouverte avant que quelqu’un la repère. Ce risque justifie à lui seul un audit.

Audit de code, test d’intrusion et sécurité d’API

On confond souvent trois exercices de sécurité qui se ressemblent. L’audit de code examine le code source. Le test d’intrusion, ou pentest, attaque l’application en fonctionnement, comme le ferait un attaquant qui n’a pas accès au code. La sécurité d’API couvre les risques propres aux interfaces exposées à d’autres applications. L’OWASP, une fondation à but non lucratif dédiée à la sécurité des applications web, classe ces risques dans un Top 10 réservé aux API.

ExerciceMatière examinéePoints fortsLimites
Audit de code PHPCode source, dépendances, configurationTrouve les failles jusque dans les fonctions rarement utilisées et mesure la dette techniqueCouvre mal ce qui dépend du serveur réel en production
Test d’intrusionApplication en fonctionnement, vue de l’extérieurProuve qu’une faille s’exploite vraimentNe couvre que les parcours testés pendant la mission
Sécurité d’APIPoints d’accès de l’API, jetons, droits par objetCible les risques des architectures où le front et le back sont séparésLaisse de côté les pages rendues par le serveur

Une application PHP qui sert à la fois des pages HTML et une API a besoin d’un audit de code et d’un examen de la sécurité de son API. Un audit de code décrit l’état de l’application à une date donnée et n’a pas valeur de certification : il ne délivre aucun label et ne garantit pas l’absence de faille. Quand un marché public ou un secteur régulé exige un prestataire d’audit qualifié PASSI par l’ANSSI, l’Agence nationale de la sécurité des systèmes d’information, demandez cette qualification au prestataire avant de signer.

Le périmètre d’un audit de code PHP

Un audit couvre cinq domaines. Le temps passé sur chacun dépend de la taille de l’application et des alertes à l’origine de l’audit.

Les versions et les dépendances

L’auditeur relève la version de PHP, celle du framework et celle de chaque paquet listé dans le fichier composer.lock. La commande composer audit compare ces paquets aux avis de sécurité publiés sur Packagist et signale aussi les paquets abandonnés par leurs auteurs. L’auditeur fait le même travail sur les dépendances JavaScript du front, avec npm audit. L’OWASP place les failles de la chaîne d’approvisionnement logicielle au troisième rang de son Top 10 2025, publié en novembre 2025. Une application dont les dépendances n’ont pas été mises à jour depuis trois ans contient presque toujours des paquets touchés par une faille connue.

La configuration

Une partie des failles vient des réglages du serveur. L’auditeur vérifie le fichier php.ini de production : display_errors désactivé pour que les messages d’erreur ne montrent pas les chemins et les requêtes, expose_php désactivé, cookies de session en HttpOnly, Secure et SameSite, allow_url_include désactivé. Il cherche aussi les mots de passe écrits dans le dépôt, y compris dans l’historique Git, un fichier phpinfo.php oublié, un phpMyAdmin accessible depuis Internet, ou un dossier qui reçoit les fichiers envoyés par les utilisateurs et dans lequel le serveur exécute le code PHP. La mauvaise configuration est au deuxième rang du Top 10 OWASP 2025.

L’authentification et les autorisations

L’auditeur examine quatre points de l’authentification : le stockage des mots de passe (password_hash() et password_verify()), le renouvellement de l’identifiant de session après la connexion avec session_regenerate_id(), la limite du nombre d’essais et la double authentification des comptes d’administration.

Les autorisations demandent plus de temps, car aucun outil ne les vérifie à la place d’un humain. L’auditeur teste si un utilisateur connecté peut lire ou modifier une facture, un dossier ou un compte qui ne lui appartient pas, en changeant un identifiant dans l’URL. Ce défaut de contrôle d’accès est en tête du Top 10 OWASP depuis 2021 et du Top 10 réservé aux API depuis sa première édition en 2019.

Le traitement des données saisies

Toute donnée qui vient de l’utilisateur ($_GET, $_POST, $_COOKIE, les fichiers envoyés, les en-têtes HTTP) doit être validée en entrée et échappée en sortie. L’auditeur suit le chemin de ces données jusqu’aux fonctions sensibles : requêtes SQL, affichage HTML, inclusion de fichiers, commandes système, désérialisation.

Les tests, la revue de code et les journaux

L’auditeur mesure enfin la capacité de l’équipe à corriger sans casser. Il regarde la couverture des tests automatisés sur les parcours critiques (connexion, paiement, export de données), le niveau atteint par l’analyse statique avec PHPStan ou Psalm, la présence d’une revue de code avant chaque mise en production, et la façon dont l’application se déploie. Il vérifie aussi que les connexions, les erreurs et les actions d’administration laissent une trace dans des journaux que quelqu’un consulte.

Le livrable reprend ces cinq domaines avec, pour chacun, les problèmes relevés, leur priorité selon les objectifs du client et des recommandations que l’équipe peut appliquer.

Les failles PHP les plus fréquentes dans un code ancien

Les mêmes vulnérabilités PHP reviennent dans les applications écrites avant que les frameworks modernes se généralisent. Chacune laisse un signe reconnaissable dans le code.

FailleSigne dans le codeCorrectif
Injection SQLRequête construite en collant une variable : "... WHERE id = " . $_GET['id']Requêtes préparées avec PDO ou l’ORM du framework
Cross-site scripting (XSS)Variable affichée avec echo sans échappementhtmlspecialchars() à l’affichage, ou un moteur de templates qui échappe par défaut (Twig, Blade)
Inclusion de fichierinclude($_GET['page'] . '.php')Liste fermée des pages autorisées
Injection d’objetunserialize() appliqué à un cookie ou à un champ de formulairejson_decode() pour les données venues de l’extérieur
Injection de commandeexec(), shell_exec() ou system() avec une donnée saisieSupprimer l’appel, ou escapeshellarg() sur chaque argument
Envoi de fichiers non contrôléFichier enregistré sous son nom d’origine dans un dossier publicContrôle du type réel, nom généré par le serveur, dossier sans exécution PHP
Mots de passe faiblesmd5($password) ou sha1($password)password_hash(), avec migration des anciens mots de passe à la connexion suivante
Falsification de requête (CSRF)Formulaire de modification sans jetonJeton CSRF vérifié sur chaque action qui modifie des données

Les outils d’analyse statique repèrent une partie de ces failles. Psalm propose une analyse de propagation (psalm --taint-analysis) qui suit une donnée saisie jusqu’à une fonction sensible. Ces outils ignorent les règles métier : ils ne savent pas qu’un commercial n’a pas le droit de voir les contrats d’une autre agence. Seul un développeur qui lit le code peut vérifier ce genre de règle.

Prioriser les correctifs

Un premier audit d’une application ancienne relève souvent plusieurs dizaines de problèmes. On peut rarement tout corriger d’un coup, donc l’ordre compte. Classez chaque faille selon quatre critères :

  • l’exposition, selon que la faille est joignable sans compte, avec un compte utilisateur, ou seulement depuis le réseau interne
  • l’impact, selon qu’une exploitation donne accès à des données personnelles, à des paiements, ou au serveur entier
  • la facilité d’exploitation, plus grande quand un code d’attaque circule publiquement pour cette faille
  • le coût du correctif, d’une ligne de configuration à plusieurs semaines de travail

Le score CVSS, la note de gravité de 0 à 10 jointe à chaque avis de sécurité, aide à classer les failles des dépendances, mais il ignore l’usage que l’application fait de la dépendance : une faille notée critique dans une fonction que l’application n’appelle jamais passe après une faille moyenne sur la page de connexion.

Trois niveaux suffisent en général. Les failles exposées sans compte et faciles à exploiter se corrigent dans la semaine, même par un correctif provisoire. Les failles qui demandent un compte ou un travail plus long se corrigent dans le mois. La montée de version de PHP et du framework, le remboursement de la dette technique et l’ajout de tests forment un plan sur plusieurs mois. Si l’application traite des données personnelles, gardez en tête qu’une violation de données doit être notifiée à la CNIL dans les 72 heures après sa découverte, selon l’article 33 du RGPD.

Prioriser les correctifs après un audit de code PHP : cette semaine, ce mois-ci, ce trimestre

Corriger progressivement ou refondre l’application ?

Une fois les urgences traitées, il faut décider si l’on corrige le code par étapes ou si on le reconstruit. L’audit donne les éléments pour choisir.

CritèreCorrection progressiveRefonte
ArchitectureTient encore, les problèmes sont localisésNe correspond plus au produit ni aux usages
Écart de versionsUne ou deux branches de PHP et du framework à rattraperFramework abandonné, code antérieur à PHP 7
TestsUne base de tests existe ou peut s’écrire sur les parcours critiquesLe code est trop couplé pour être testé sans le réécrire
Évolutions prévuesPeu de nouvelles fonctionnalités dans les deux ansUne feuille de route chargée que le code actuel ralentit
ÉquipeDes développeurs connaissent le codePlus personne ne le maîtrise

La correction progressive est souvent le bon choix, parce qu’elle protège l’application vite et rembourse la dette technique au fil des sprints. La refonte se justifie quand chaque correctif coûte plus cher que la reconstruction du module concerné. Les frameworks modernes et l’IA ont fait baisser le coût d’un logiciel sur mesure : ce qui coûte cher, c’est de continuer à corriger un code qui ne correspond plus au produit, ou de lancer une refonte sans l’état des lieux qui en fixe le périmètre.

Pour le SaaS de dossiers de location Greenloc, l’audit technique de Lonestone a montré une dette qui ralentissait chaque développement. Lonestone a donc recommandé une refonte complète du back-end, menée pendant que la plateforme restait en production.

Migrer sans interrompre le service

Pendant une montée de version comme pendant une refonte, l’application doit continuer à servir ses utilisateurs. Quatre précautions évitent la plupart des interruptions.

  1. Écrivez des tests de caractérisation avant de toucher au code. Ils enregistrent le comportement actuel des parcours critiques, bugs compris, et signalent tout changement involontaire.
  2. Montez de version une branche à la fois (7.4 vers 8.0, puis 8.1, et ainsi de suite) plutôt que d’un seul saut. Le standard PHPCompatibility de PHP_CodeSniffer liste les incompatibilités avant chaque étape, puis Rector automatise une partie des réécritures.
  3. Préparez la nouvelle version sur un second serveur identique à la production, puis basculez le trafic quand elle est validée. L’ancien serveur reste prêt pour un retour en arrière.
  4. Pour une refonte, remplacez l’application module par module. Une passerelle placée devant les deux versions envoie chaque route vers l’ancien code ou vers le nouveau. Les utilisateurs passent ainsi au nouveau code fonctionnalité par fonctionnalité. Migrez les données par lots et vérifiez chaque lot.
graph TD
    A["Audit du code PHP"] --> B["Correctifs urgents<br/>en production"]
    B --> C["Tests de caractérisation<br/>sur les parcours critiques"]
    C --> D{"Correction ou refonte ?"}
    D -->|Correction| E["Montée de version<br/>une branche PHP à la fois"]
    D -->|Refonte| F["Nouveau module derrière<br/>une passerelle"]
    E --> G["Bascule sur un serveur<br/>préparé, retour arrière possible"]
    F --> H["Bascule route par route<br/>et migration des données par lots"]
    H --> F

La refonte progressive prend plus de temps qu’un remplacement d’un seul coup. En revanche, une bascule ratée ne bloque qu’un module, pendant que le reste de l’application continue de servir les utilisateurs.

Les actions à lancer cette semaine

Ces actions demandent peu de temps et réduisent l’exposition avant même le début de l’audit :

  1. Relevez la version de PHP du serveur (php -v), celle du framework et le contenu du fichier composer.lock.
  2. Lancez composer audit et notez les avis de sécurité classés critiques ou élevés.
  3. Désactivez display_errors en production, supprimez les fichiers phpinfo.php et fermez l’accès public aux outils d’administration comme phpMyAdmin.
  4. Cherchez les mots de passe et les clés d’API présents dans le dépôt et son historique, puis changez ceux que vous trouvez.
  5. Activez la double authentification sur l’hébergement, le dépôt de code et le back-office de l’application.
  6. Vérifiez que les sauvegardes tournent et restaurez-en une sur un serveur de test.
  7. Assurez-vous que les connexions, les erreurs et les actions d’administration sont journalisées.
  8. Planifiez la montée vers une branche de PHP encore maintenue, PHP 8.3 ou plus récente, puisque PHP 8.2 perd ses correctifs le 31 décembre 2026.

Application PHP : 8 actions à lancer cette semaine, des versions à relever jusqu’à la montée vers PHP 8.3

Faire auditer son application PHP

Un audit de code PHP donne en quelques jours ce qu’une équipe absorbée par la production a rarement le temps de produire : la liste des failles, leur ordre de correction et une recommandation argumentée entre correction et refonte. Une version de PHP sans correctifs suffit déjà à justifier un audit.

Lonestone réalise des audits applicatifs de 1 à 5 jours, à 800 € HT par jour pour l’audit de code comme pour l’audit de cybersécurité, qui ajoute un test d’intrusion. L’agence a travaillé pour plus de 200 clients depuis 2014, avec des ingénieurs qui ont pour la plupart 10 à 25 ans d’expérience. Quand l’audit conclut à une refonte, l’équipe, qui travaille quasi exclusivement en TypeScript, reconstruit le back-end module par module, par exemple en NestJS, pendant que l’ancienne application reste en service. Pour une application qu’il faut ensuite suivre au quotidien, la tierce maintenance applicative prend le relais.

FAQ

Questions fréquentes

Qu’est-ce qu’un audit de code PHP ?

Un audit de code PHP est l’analyse du code source d’une application PHP existante pour évaluer sa sécurité et sa qualité. Il couvre les versions de PHP, du framework et des dépendances, la configuration du serveur, l’authentification, le contrôle des accès, le traitement des données saisies, les tests et les journaux. Le livrable liste les problèmes relevés, les classe par priorité et recommande une suite : correction progressive ou refonte.

Combien coûte un audit de code PHP ?

Le prix d’un audit de code dépend de la taille de l’application et du périmètre demandé. Chez Lonestone, l’audit de code est facturé 800 € HT par jour et dure de 1 à 5 jours, soit de 800 à 4 000 € HT. Un audit de cybersécurité avec test d’intrusion peut le compléter au même tarif journalier. Lonestone propose un échange et un devis gratuits pour estimer le nombre de jours.

Quels outils utiliser pour analyser la sécurité d’un code PHP ?

Les outils les plus courants sont composer audit, qui compare les dépendances aux avis de sécurité publiés sur Packagist, PHPStan et Psalm pour l’analyse statique, et l’analyse de propagation de Psalm, qui suit une donnée saisie jusqu’aux fonctions sensibles. Rector et PHPCompatibility aident à préparer une montée de version. Ces outils ne vérifient pas les règles métier, comme le droit d’un utilisateur à consulter un dossier : cette vérification demande une lecture humaine du code. Pour une API, l’OWASP publie aussi un classement des failles propres aux API.

Une application en PHP 7 est-elle dangereuse ?

PHP 7.4, dernière version de la branche 7, ne reçoit plus de correctifs de sécurité depuis le 28 novembre 2022. Une faille découverte depuis dans le langage reste ouverte sur un serveur qui l’utilise, sauf si la distribution Linux du serveur publie ses propres correctifs, comme le font certaines distributions à support long. L’application n’est pas forcément compromise, mais le risque augmente avec le temps. La montée vers PHP 8.3 ou une version plus récente est la mesure à planifier en priorité.

Faut-il réécrire une vieille application PHP ?

Une correction progressive suffit souvent quand l’architecture tient encore, que l’écart de versions reste raisonnable et que des tests peuvent couvrir les parcours critiques. La refonte se justifie quand le framework est abandonné, que personne ne maîtrise plus le code ou que chaque correctif coûte plus cher que la reconstruction du module concerné. Dans ce cas, elle se mène module par module, l’ancienne application restant en service jusqu’à la bascule complète. Un audit de code fournit les éléments pour choisir, à commencer par la mesure de la dette technique.

Un audit de code est-il une certification de sécurité ?

Non. Un audit de code donne un état des lieux de l’application à une date donnée, avec des recommandations, sans délivrer de label ni garantir l’absence de faille. Certains secteurs régulés et marchés publics exigent un prestataire d’audit qualifié PASSI par l’ANSSI : cette qualification se vérifie auprès du prestataire avant de signer.

Lonestone conçoit et développe vos produits numériques

On discute de votre projet ?

Échange gratuit et sans engagement, directement avec un expert du sujet. Devis sous 48h.

Contacter l'équipe
de Lonestone