WordPress
24 juin 2026

Webshells camouflés dans un module PrestaShop : les détecter

Laptop screen shows a Prestashop marketplace page with a large padlock badge overlaying the content, signaling security.

Une boutique PrestaShop se comporte bizarrement, vous suspectez une faille, vous lancez un scan anti-malware, il remonte un fichier suspect, vous le supprimez… et vous pensez en avoir fini ? C’est exactement là que la plupart des nettoyages échouent. Un webshell isolé est rarement seul, et les plus dangereux ne ressemblent justement pas à un webshell. Voici comment on mène un audit profond après une suspicion de compromission.

Ce que vous allez apprendre :

  • Pourquoi un scan anti-malware à signatures ne suffit jamais après une compromission
  • Les emplacements de camouflage où un fichier PHP n’a rien à faire sur PrestaShop
  • Comment qualifier un fichier intrus en croisant chemin, taille, hash et date
  • Notre checklist d’audit, de nettoyage et de durcissement réutilisable

C’est un type d’intervention qu’on prend de plus en plus souvent en urgence. Le scénario est presque toujours le même : un comportement anormal côté boutique, parfois un signalement de l’hébergeur, parfois juste une intuition de l’équipe technique. On lance un premier scan, on trouve un fichier qui ne devrait pas être là, on le supprime, et la tentation est grande de refermer le dossier.

👉 Sauf qu’un attaquant qui a réussi à déposer un fichier en dépose presque toujours plusieurs, à des endroits différents, avec des niveaux de discrétion variés.

Trouver le premier webshell, ce n’est pas la fin de l’audit. C’est le début. La vraie question n’est jamais « est-ce qu’il y en a un ? » mais « combien, où, et depuis quand ? »

Chez Mintfull, on a fait ce diagnostic suffisamment de fois pour en avoir tiré une méthode. Elle repose sur une idée simple : sur PrestaShop, on connaît parfaitement l’arborescence native attendue. Tout fichier PHP qui apparaît là où il ne devrait jamais y en avoir est un signal bien plus fort qu’un scan superficiel.

Pourquoi un scan anti-malware ne suffit pas

Les scanners à signatures font un travail utile : ils reconnaissent des webshells connus, des chaînes caractéristiques, des fonctions sensibles comme eval(), base64_decode() ou assert(). Mais ils ont trois angles morts qu’un attaquant un minimum sérieux exploite sans effort.

  • L’obfuscation. Un payload encodé, fragmenté ou reconstruit à l’exécution échappe facilement aux signatures statiques.
  • Les outils « légitimes ». Un gestionnaire de fichiers PHP autonome (type « Tiny File Manager ») est un logiciel parfaitement réel et open source. Déposé à la racine d’un projet, il ne déclenche pas toujours d’alerte : ce n’est pas un malware, c’est un outil. Sauf qu’entre les mains d’un attaquant, c’est une porte d’entrée complète.
  • Le contexte. Un scanner regarde le contenu d’un fichier. Il ne sait pas qu’un fichier PHP dans un dossier de traduction n’a, sur PrestaShop, aucune raison d’exister.

👉 C’est précisément ce dernier point qui fait toute la différence. Le meilleur détecteur de webshell, sur un CMS dont on connaît la structure, ce n’est pas une signature. C’est l’incohérence entre ce qu’on trouve et ce que l’arborescence native devrait contenir.

Audit ciblé : les chemins improbables d’abord

Quand on suspecte une compromission, on ne part pas dans un scan exhaustif et indifférencié. On va d’abord regarder les endroits où un fichier PHP est intrinsèquement suspect. Voici les familles de camouflage qu’on rencontre le plus souvent.

Du PHP dans les dossiers de traduction

Les dossiers de traduction d’un module ou du thème (typiquement translations/, lang/, ou leurs équivalents) contiennent des fichiers de langue : des tableaux de chaînes, parfois du .xlf, du .po. Ce qu’ils ne contiennent jamais nativement, c’est un fichier PHP exécutable qui fait autre chose que retourner des traductions.

👉 Un .php qui traîne dans une arborescence de langue est l’un des signaux les plus fiables qu’on connaisse. C’est un emplacement « propre » aux yeux d’un humain pressé, rarement inspecté, et qui survit aux mises à jour partielles.

Les faux fichiers de classe et de module

Autre grand classique : un fichier nommé pour ressembler à une classe légitime ou à un fichier de module, placé dans classes/ ou dans le dossier d’un module. Le nom imite la convention PrestaShop, l’extension est correcte, l’œil glisse dessus. Mais le contenu n’a rien d’une classe métier : c’est un point d’entrée.

La parade tient à la connaissance de la structure attendue. Un vrai module a une arborescence prévisible, déclarée dans son propre code. Un fichier de classe orphelin, qui n’est référencé nulle part et ne correspond à aucune entité connue du module, mérite une inspection immédiate.

Les faux scripts d’upgrade dans l’admin

Le dossier d’administration de PrestaShop contient légitimement des scripts d’upgrade et de maintenance. C’est un terrain idéal pour le camouflage : un fichier déposé là, avec un nom qui évoque une routine de mise à jour, se fond dans le décor. Personne ne se méfie d’un script d’upgrade dans le dossier qui en contient déjà.

Le camouflage le plus efficace n’est jamais un fichier exotique dans un coin bizarre. C’est un fichier ordinaire, au bon endroit, avec le bon nom — sauf qu’il n’appartient pas à l’install d’origine.

Les incohérences avec l’arborescence native

Au-delà de ces trois familles, le principe général est toujours le même : comparer ce qu’on a sous les yeux avec ce qu’une install saine devrait contenir. Un dossier qui n’a normalement aucun PHP en contient un. Un module standard du marché embarque un fichier qui ne fait pas partie de sa distribution officielle. Une arborescence présente une asymétrie que rien ne justifie.

Quelques commandes d’audit pour cadrer la recherche

Ces commandes sont volontairement génériques et défensives. Elles servent à cartographier les anomalies, pas à exploiter quoi que ce soit. On les lance toujours sur une copie ou en lecture, jamais à l’aveugle sur la prod sans précaution.

Lister les fichiers PHP apparus récemment (utile quand on a une fenêtre d’incident approximative) :

# Fichiers PHP modifiés/créés depuis une date de référence
find . -type f -name "*.php" -newermt "2026-01-01" -printf "%TY-%Tm-%Td %p\n" | sort

Chercher du PHP là où il ne devrait pas y en avoir, comme les dossiers de traduction :

# PHP dans des arborescences de langue/traduction
find . -type d \( -name "translations" -o -name "lang" -o -name "mails" \) \
  -exec find {} -type f -name "*.php" -print \;

Quand le projet est versionné (et il devrait l’être), Git est votre meilleur allié : tout fichier non suivi ou modifié hors release est immédiatement visible.

# Fichiers non suivis ou modifiés par rapport au dépôt
git status --porcelain
git diff --stat HEAD

Enfin, la comparaison à une install saine de la même version reste la référence absolue : on télécharge la distribution officielle du module ou du cœur concerné, et on diff.

# Comparer un module suspect à une copie saine de la même version
diff -rq ./modules/un_module/ /chemin/vers/copie_saine/un_module/

👉 Aucune de ces commandes ne prouve à elle seule qu’un fichier est malveillant. Elles produisent une liste de candidats. La qualification, c’est l’étape suivante.

Qualifier un fichier intrus sans se tromper

Un fichier qui sort de l’audit n’est pas forcément un webshell. Il peut s’agir d’un cache légitime, d’un fichier généré, d’un reliquat de module mal désinstallé. Pour trancher proprement et éviter les faux positifs, on croise systématiquement quatre dimensions.

  • Le chemin. L’emplacement est-il cohérent avec l’arborescence native attendue ? Un PHP dans un dossier de langue est suspect par construction, indépendamment de son contenu.
  • La taille. Un gestionnaire de fichiers complet a une empreinte caractéristique. Un fichier de quelques centaines d’octets bourré de fonctions sensibles aussi. Une taille qui détonne par rapport aux fichiers voisins légitimes est un indice.
  • Le hash. On calcule l’empreinte du fichier et on la compare à celle du même fichier dans une distribution officielle. Si le hash ne correspond à aucun fichier connu de la version installée, le fichier n’appartient pas à l’install.
  • La date de dépôt. Les métadonnées temporelles (création, dernière modification) regroupent souvent les dépôts en grappes. Plusieurs fichiers déposés dans la même fenêtre courte racontent une seule et même intrusion.

👉 C’est le croisement qui fait la preuve. Un seul de ces critères peut induire en erreur ; les quatre ensemble dessinent une histoire cohérente.

Le shell ancien qui précède les autres

Un détail revient assez souvent pour mériter d’être nommé : dans une famille de fichiers déposés en grappe à une date donnée, on trouve parfois un fichier distinct et nettement plus ancien. Une porte d’entrée discrète, posée bien avant, qui a probablement servi de point d’appui persistant pour déposer ensuite les autres outils.

C’est exactement la raison pour laquelle on ne s’arrête jamais au premier fichier trouvé, ni même à la grappe la plus évidente. La date qui détonne dans le lot est souvent la plus instructive : elle indique le vrai point d’entrée initial, celui qu’il faut absolument comprendre pour s’assurer que la faille d’origine est bien refermée.

Le fichier le plus récent vous dit comment l’attaquant a travaillé. Le fichier le plus ancien vous dit comment il est entré. C’est le second qui compte vraiment.

Nettoyer puis durcir : la checklist

Une fois les fichiers intrus qualifiés, le nettoyage n’est que la moitié du travail. Supprimer les webshells sans refermer la faille d’origine, c’est garantir une réinfection à court terme. Voici notre séquence.

Où regarder en priorité

  1. Les dossiers de traduction et de langue de chaque module et du thème.
  2. Le dossier d’administration et ses scripts d’upgrade/maintenance.
  3. Les dossiers classes/ et la racine de chaque module, à la recherche de faux fichiers de classe.
  4. Les dossiers censés ne contenir que des assets (images, traductions, cache) mais qui hébergent du PHP exécutable.
  5. Tout fichier dont la date de modification tombe dans la fenêtre de l’incident.

Quoi vérifier après suppression

  • Repasser un audit complet : une seconde grappe se révèle souvent une fois la première nettoyée.
  • Inspecter les tâches planifiées (cron) et les éventuels jobs qui pourraient redéployer un payload.
  • Contrôler les comptes administrateurs : un compte ajouté ou un mot de passe modifié pendant l’intrusion.
  • Vérifier l’intégrité du cœur et des modules par comparaison à une distribution officielle.
  • Relire les logs serveur autour de la date du fichier le plus ancien pour comprendre le vecteur d’entrée.

Comment durcir durablement

  • Droits fichiers stricts. Pas d’écriture inutile sur les dossiers qui n’en ont pas besoin ; séparation propre entre l’utilisateur applicatif et le serveur web.
  • Surveillance d’intégrité. Un suivi des fichiers (idéalement via le versioning Git du projet, complété par un contrôle d’intégrité) qui alerte dès qu’un fichier apparaît ou change hors déploiement.
  • Rotation des accès. Renouveler les mots de passe admin, les clés API, les accès SFTP/SSH et de base de données après tout incident avéré.
  • Mises à jour. Maintenir le cœur, les modules et le thème à jour ferme la majorité des vecteurs d’entrée. Une compromission part presque toujours d’un composant obsolète ou d’une vulnérabilité connue non corrigée. Sur ce point, notre article sur ce qu’il faut savoir sur PrestaShop 9 donne le contexte de version.

Notre avis chez Mintfull

La leçon qu’on retient de ces interventions est contre-intuitive : sur PrestaShop, la meilleure détection ne vient pas d’un outil plus puissant, mais d’une meilleure connaissance de la structure native. Un fichier PHP dans un dossier de traduction, un faux script d’upgrade dans l’admin, une classe orpheline qui ne correspond à rien — ce sont des signaux qu’aucune signature ne remplace.

Un scan rapide vous dit si quelque chose de connu traîne. Un audit ciblé vous dit ce qui n’a rien à faire là. Sur un CMS dont on maîtrise l’arborescence, le second l’emporte presque toujours.

👉 Et la règle d’or, celle qui résume tout : ne jamais s’arrêter au premier fichier compromis trouvé. La grappe visible cache souvent un point d’appui plus ancien, et c’est lui qui détermine si la faille est vraiment refermée. Un nettoyage qui ignore le vecteur d’entrée n’est qu’un répit.

Si votre boutique rame ou se comporte anormalement et que vous hésitez entre incident de performance et compromission, notre article sur le back-office PrestaShop lent aide à faire la part des choses avant de conclure à une attaque.

FAQ : webshells et compromission PrestaShop

Un scan anti-malware suffit-il à nettoyer une boutique compromise ?

Non, pas seul. Un scan à signatures détecte les webshells connus, mais passe à côté des outils « légitimes » détournés, des payloads obfusqués et surtout des fichiers placés à des emplacements anormaux. Il faut le compléter par un audit ciblé de l’arborescence native et une comparaison à une install saine.

Pourquoi chercher du PHP dans les dossiers de traduction en priorité ?

Parce que ces dossiers ne contiennent jamais nativement de PHP exécutable. Un .php qui y apparaît est donc un signal très fiable, indépendamment de son contenu. C’est un emplacement rarement inspecté, qui survit aux mises à jour partielles et qui paraît « propre » à un œil pressé — exactement ce que recherche un attaquant.

Comment distinguer un vrai webshell d’un faux positif ?

En croisant quatre dimensions : le chemin (cohérent ou non avec l’arborescence native), la taille (atypique par rapport aux fichiers voisins), le hash (correspond-il à un fichier de la distribution officielle ?) et la date de dépôt (regroupement en grappe révélateur). Un seul critère peut tromper ; les quatre ensemble tranchent.

Pourquoi ne faut-il pas s’arrêter au premier fichier trouvé ?

Parce qu’une intrusion dépose presque toujours plusieurs fichiers, et qu’un point d’appui plus ancien et discret précède souvent la grappe visible. Tant qu’on n’a pas identifié le fichier le plus ancien et compris le vecteur d’entrée, on n’a aucune garantie que la faille d’origine est refermée. Le risque de réinfection reste entier.


Vous suspectez une compromission sur votre boutique PrestaShop, ou vous voulez vous assurer qu’un nettoyage passé était bien complet ?

👉 Notre agence PrestaShop mène des audits de sécurité méthodiques : cartographie des emplacements à risque, qualification des fichiers intrus, identification du vecteur d’entrée, puis nettoyage et durcissement durable. Parce qu’une boutique compromise, ce n’est pas qu’un fichier à supprimer : c’est une faille à comprendre et à refermer.

Nous vous recommandons aussi