Sécurité PrestaShop — Retour d’incident
Référencée CVE-2026-54159 / GHSA-m5f5-28qr-9g9r, cette vulnérabilité est classée CVSS 10.0.
Nous avons récemment analysé une compromission réelle sur une boutique utilisant encore ps_facetedsearch 3.8.0. Les journaux Apache ont permis de reconstruire une grande partie de l’attaque, presque seconde par seconde.
Le nom de la boutique, son domaine, ses identifiants et certaines informations techniques ont volontairement été anonymisés.
CVE-2026-54159 : quelles versions sont concernées ?
D’après l’avis de sécurité officiel PrestaShop, les versions concernées sont :
ps_facetedsearch >= 3.0.0
ps_facetedsearch < 4.0.4
La correction est intégrée à partir de :
ps_facetedsearch 4.0.4
Dans notre cas, la boutique fonctionnait encore avec :
Navigation à facettes 3.8.0
Elle se trouvait donc directement dans la plage des versions vulnérables.
Comment fonctionne la vulnérabilité ?
Le problème concerne le traitement de certaines valeurs utilisées par les filtres de Navigation à facettes, notamment les filtres de type curseur comme le prix ou le poids.
Dans les versions vulnérables, certaines données peuvent atteindre le mécanisme de cache du module puis être relues au travers d’une désérialisation PHP insuffisamment sécurisée.
Cela ouvre la possibilité d’une PHP Object Injection. Une donnée spécialement construite peut conduire à l’écriture d’un fichier PHP sur le serveur.
Une fois ce fichier accessible depuis Internet, il peut devenir un webshell permettant l’exécution de commandes à distance.
Requête HTTP Front-Office
↓
Navigation à facettes
↓
Donnée malveillante
↓
Cache ps_facetedsearch
↓
PHP Object Injection
↓
Écriture d'un fichier PHP
↓
Webshell
↓
Remote Code Execution
Le point particulièrement critique est qu’aucune authentification au Back-Office n’est nécessaire pour déclencher l’exploitation.
Analyse forensic : ce que montrent réellement les logs Apache
Lors de l’analyse, nous disposions d’environ quinze jours de journaux Apache.
Nous avons corrélé plusieurs informations : adresse IP, date et heure, méthode HTTP, URL, code de réponse, fichiers détectés par notre scanner malware, dates de création des fichiers et versions des modules PrestaShop.
Cette corrélation est essentielle : un fichier PHP suspect ne permet pas, à lui seul, de reconstruire une compromission.
24 septembre à 18:37 : début de la séquence critique
Le 24 septembre 2026 à 18:37:13, une adresse IP commence
une séquence directement liée à ps_facetedsearch.
86.54.25.179 - - [24/Sep/2026:18:37:13 +0200]
"GET /modules/ps_facetedsearch/ps_facetedsearch-clear-cache.php?token=[REDACTED] HTTP/1.1"
200
Immédiatement après, la même adresse effectue une succession très rapide de requêtes POST sur une catégorie PrestaShop :
86.54.25.179 - - [24/Sep/2026:18:37:13 +0200]
"POST /index.php?controller=category&id_category=7 HTTP/1.1"
200
86.54.25.179 - - [24/Sep/2026:18:37:14 +0200]
"POST /index.php?controller=category&id_category=7 HTTP/1.1"
200
86.54.25.179 - - [24/Sep/2026:18:37:15 +0200]
"POST /index.php?controller=category&id_category=7 HTTP/1.1"
200
[...]
86.54.25.179 - - [24/Sep/2026:18:37:18 +0200]
"POST /index.php?controller=category&id_category=7 HTTP/1.1"
200
Au total, une dizaine de POST sont envoyés en quelques secondes.
Pris isolément, ces POST ne suffisent pas à démontrer l’exploitation de
CVE-2026-54159 : un access.log Apache classique ne conserve
pas le contenu du corps POST.
C’est ce qui se produit immédiatement après qui devient particulièrement intéressant.
18:37:19 : un shell PHP répond aux commandes
Une seconde seulement après la dernière série de POST, la même IP appelle :
86.54.25.179 - - [24/Sep/2026:18:37:19 +0200]
"GET /test.php?c=whoami HTTP/1.1"
200
Puis, durant la même seconde :
86.54.25.179 - - [24/Sep/2026:18:37:19 +0200]
"GET /img/test.php?c=whoami HTTP/1.1"
200
Une tentative similaire sur un fichier inexistant répond correctement en 404 :
86.54.25.179 - - [24/Sep/2026:18:37:19 +0200]
"GET /testphp?c=whoami HTTP/1.1"
404
Nous avons donc :
/test.php → HTTP 200
/img/test.php → HTTP 200
/testphp → HTTP 404
Le paramètre transmis contient ici la commande système
whoami.
À cet instant, la présence et l’utilisation de fichiers permettant l’exécution de commandes sur le serveur sont confirmées.
La proximité temporelle entre l’activité sur
ps_facetedsearch, les POST successifs et l’apparition immédiate des shells rend le lien avec CVE-2026-54159 particulièrement fort.
Nous parlons néanmoins de point d’entrée très fortement probable plutôt que de preuve absolue du payload initial, puisque le contenu exact des requêtes POST n’était pas journalisé.
22:48 : utilisation du premier shell pour déposer c99.php
Quelques heures plus tard, l’adresse
86.54.25.179 revient sur le serveur.
À 22:48:18 :
86.54.25.179 - - [24/Sep/2026:22:48:18 +0200]
"POST /test.php?a=put&f=c99.php HTTP/1.1"
200
Cette ligne est particulièrement significative : le premier shell est
utilisé pour déposer un nouveau fichier nommé
c99.php.
Quinze secondes plus tard :
86.54.25.179 - - [24/Sep/2026:22:48:33 +0200]
"GET /c99.php HTTP/2.0"
403
L’opérateur revient ensuite sur le premier shell et demande un listing des fichiers :
86.54.25.179 - - [24/Sep/2026:22:48:49 +0200]
"GET /test.php?c=ls HTTP/2.0"
200
Nous ne sommes donc plus face à un scanner automatisé recherchant une vulnérabilité : le serveur est utilisé activement après la compromission.
22:58 : installation d’un second webshell
Dix minutes plus tard, le même accès est utilisé pour déposer
bfms.php.
86.54.25.179 - - [24/Sep/2026:22:58:33 +0200]
"POST /test.php?a=put&f=bfms.php HTTP/1.1"
200
Huit secondes plus tard :
86.54.25.179 - - [24/Sep/2026:22:58:41 +0200]
"GET /bfms.php HTTP/2.0"
200 77171
Plusieurs interactions POST suivent immédiatement :
22:58:45 POST /bfms.php → 200
22:58:49 POST /bfms.php → 200
22:59:05 POST /bfms.php → 200
22:59:20 POST /bfms.php → 200
22:59:27 POST /bfms.php → 200
La succession de requêtes et la taille variable des réponses sont compatibles avec l’utilisation interactive d’un gestionnaire de fichiers ou d’un webshell.
L’attaquant dispose désormais de plusieurs mécanismes d’accès au serveur.
22:59 : apparition d’Adminer et tentative d’accès à MySQL
Environ une minute après l’utilisation de bfms.php,
un autre fichier devient accessible :
86.54.25.179 - - [24/Sep/2026:22:59:44 +0200]
"GET /themes/adminer.php HTTP/2.0"
200
Les ressources d’Adminer sont ensuite chargées :
GET /themes/adminer.php?file=default.css&version=5.4.2 → 200
GET /themes/adminer.php?file=functions.js&version=5.4.2 → 200
GET /themes/adminer.php?file=logo.png&version=5.4.2 → 200
Puis :
86.54.25.179 - - [24/Sep/2026:23:00:12 +0200]
"POST /themes/adminer.php HTTP/2.0"
302
La requête suivante contient explicitement le nom du compte MySQL de la boutique, anonymisé ici :
86.54.25.179 - - [24/Sep/2026:23:00:12 +0200]
"GET /themes/adminer.php?username=[DB_USER_REDACTED] HTTP/2.0"
403
Une autre IP apparaît ensuite :
196.17.171.196 - - [24/Sep/2026:23:01:28 +0200]
"GET /themes/adminer.php?username=[DB_USER_REDACTED] HTTP/2.0"
403
196.17.171.196 - - [24/Sep/2026:23:01:46 +0200]
"POST /themes/adminer.php?username=[DB_USER_REDACTED] HTTP/2.0"
302
Nous pouvons donc confirmer une tentative d’utilisation d’Adminer avec le compte MySQL de la boutique.
Ces logs ne permettent en revanche pas de démontrer qu’une extraction complète de la base de données a effectivement eu lieu.
La compromission reste active plusieurs jours
Le problème ne s’arrête pas au 24 septembre.
Le 29 septembre, une nouvelle adresse IP utilise toujours
bfms.php :
213.139.205.186 - - [29/Sep/2026:12:04:33 +0200]
"POST /bfms.php HTTP/2.0"
200
Quelques secondes plus tard :
213.139.205.186 - - [29/Sep/2026:12:05:17 +0200]
"GET /adminer530.php HTTP/2.0"
200
Puis :
213.139.205.186 - - [29/Sep/2026:12:05:28 +0200]
"POST /adminer530.php HTTP/2.0"
302
Une tentative de connexion vers la base locale apparaît également :
GET /adminer530.php?server=127.0.0.1&username=[DB_USER_REDACTED]
403
Le paramètre server=127.0.0.1 indique explicitement une
tentative de connexion vers le serveur MySQL local.
c99.php devient ensuite accessible depuis Internet
Le 29 septembre à 19:16:20 :
147.139.178.214 - - [29/Sep/2026:19:16:20 +0200]
"GET /c99.php HTTP/1.1"
200 156540
Le fichier renvoie cette fois une réponse HTTP 200 de plus de 150 Ko.
Le webshell est donc réellement accessible depuis Internet.
30 septembre : activité encore présente quelques heures avant la détection
Le matin du 30 septembre, les accès continuent :
217.12.207.14 - - [30/Sep/2026:09:58:59 +0200]
"GET /bfms.php HTTP/2.0"
200 77181
Quelques secondes plus tard :
144.31.2.194 - - [30/Sep/2026:09:59:11 +0200]
"POST /bfms.php HTTP/2.0"
200
Puis vers 11 heures :
169.150.227.146 - - [30/Sep/2026:11:01:39 +0200]
"GET /bfms.php HTTP/2.0"
200 77170
Plusieurs POST sont ensuite enregistrés :
11:01:57 POST /bfms.php → 200
11:02:22 POST /bfms.php → 200
11:02:37 POST /bfms.php → 200
11:02:41 POST /bfms.php → 200
11:02:45 POST /bfms.php → 200
11:02:53 POST /bfms.php → 200
11:02:58 POST /bfms.php → 200
11:03:05 POST /bfms.php → 200
11:05:17 POST /bfms.php → 200
11:05:39 POST /bfms.php → 200
Dernière activité de cette séquence :
169.150.227.146 - - [30/Sep/2026:11:05:40 +0200]
"GET /bfms.php HTTP/2.0"
200
Le webshell était donc encore utilisé quelques heures avant sa découverte.
Détection par Phenix Malware Scanner
Notre scanner malware a identifié plusieurs fichiers présentant des caractéristiques anormales :
/adminer530.php
/c99.php
/img/test.php
/test.php
/themes/adminer.php
Parmi les signatures relevées :
webshell_c99
Chr_obfuscation_chain
passthru
adminer_files
adminer_mentions
Une détection statique ne suffit néanmoins jamais à conclure automatiquement qu’un fichier est malveillant.
L’un des fichiers signalés uniquement parce qu’il manipulait
error_reporting() a par exemple été identifié comme un outil
interne légitime.
Dans le cas de c99.php, test.php et
bfms.php, les journaux Apache montrent au contraire une
utilisation réelle depuis Internet.
C’est la combinaison de l’analyse statique et de l’analyse comportementale qui permet d’établir le diagnostic.
Notre méthode de corrélation
Détection malware
↓
Identification des fichiers suspects
↓
Recherche dans les journaux Apache
↓
Corrélation IP / date / heure / URL
↓
Recherche des événements immédiatement précédents
↓
Identification du composant concerné
↓
Vérification de sa version
↓
Recherche des vulnérabilités connues
↓
Reconstruction chronologique de l'incident
Chronologie synthétique de la compromission
| Date / heure | Événement observé |
|---|---|
| 24/09 – 18:37:13 | Activité liée à ps_facetedsearch |
| 18:37:13 → 18:37:18 | Environ 10 POST vers une catégorie |
| 18:37:19 | /test.php?c=whoami → HTTP 200 |
| 18:37:19 | /img/test.php?c=whoami → HTTP 200 |
| 22:48:18 | Dépôt de c99.php |
| 22:48:49 | Commande système via test.php |
| 22:58:33 | Dépôt de bfms.php |
| 22:58:41 | bfms.php accessible |
| 22:59:44 | Adminer accessible |
| 23:00:12 | Tentative d’accès MySQL |
| 29/09 | Nouvelles utilisations des webshells |
| 30/09 – 11:05 | Dernière activité observée sur bfms.php |
Correction : mise à jour immédiate vers ps_facetedsearch 4.0.4
Une fois le composant vulnérable identifié, le module a immédiatement été mis à jour :
ps_facetedsearch 3.8.0
↓
ps_facetedsearch 4.0.4
La version 4.0.4 contient le correctif officiel de CVE-2026-54159.
Un WAF ou un module de sécurité ne remplace jamais l’application du correctif du composant vulnérable.
SmallGuard Lite : une couche supplémentaire après correction
SmallGuard Lite n’était pas encore installé sur la production au moment de la compromission initiale.
Il serait donc incorrect de lui attribuer le blocage de l’exploitation initiale de CVE-2026-54159.
Il a été installé après la découverte afin d’apporter une couche complémentaire de filtrage, de surveillance et de protection du Back-Office.
Le résultat a été visible immédiatement.
Le lendemain matin :
2026-10-01 09:42:10
57.141.0.48
GET
[Back Office login]
→ BO login : pays non autorisé
2026-10-01 09:01:36
85.203.39.136
GET
[Back Office login]
→ BO login : pays non autorisé
Certaines IP sont également identifiées par les sources de réputation :
54.209.60.63
→ Firehol_webserver
184.72.121.156
→ AbuseIPDB_s100_7d
54.86.66.252
→ AbuseIPDB_s100_7d
54.175.74.27
→ AbuseIPDB_s100_7d
Par exemple, 54.209.60.63 revient plusieurs fois :
04:15:32 → bloquée
04:38:01 → bloquée
04:41:30 → bloquée
Ces événements ne permettent pas d’affirmer que ces IP sont liées à l’exploitation initiale.
Ils démontrent en revanche que l’URL du Back-Office est régulièrement sollicitée depuis des sources externes et que ces accès sont désormais filtrés avant d’atteindre normalement l’authentification PrestaShop.
L’URL du Back-Office avait-elle fuité ?
Les journaux SmallGuard indiquent clairement des requêtes :
GET [Back Office login]
Cela démontre que l’URL d’administration était connue, découverte ou testée par des systèmes externes.
Cela ne démontre pas automatiquement qu’un identifiant ou un mot de passe Back-Office avait également été récupéré.
Pour démontrer une compromission des identifiants, il faudrait notamment retrouver des POST de connexion, des échecs d’authentification répétés ou une connexion réussie depuis une adresse inconnue.
Lorsqu’une exécution de code à distance a néanmoins été obtenue sur un serveur, il est prudent de considérer les secrets accessibles au processus PHP comme potentiellement exposés.
Pourquoi supprimer uniquement le webshell ne suffit pas
Une réaction trop fréquente après ce type d’incident consiste à trouver
un fichier comme c99.php, le supprimer et considérer le
problème comme résolu.
Dans notre analyse, plusieurs mécanismes étaient déjà présents :
/test.php
/img/test.php
/c99.php
/bfms.php
/themes/adminer.php
/adminer530.php
Certains étaient encore utilisés plusieurs jours après la compromission.
Supprimer un seul fichier n’aurait donc pas supprimé les autres accès persistants ni corrigé la vulnérabilité initiale.
Notre procédure après une RCE
- conservation des logs et des fichiers avant nettoyage ;
- calcul des empreintes SHA-256 lorsque nécessaire ;
- recherche des fichiers PHP récemment créés ou modifiés ;
- comparaison avec une installation saine ;
- suppression ou mise en quarantaine des webshells ;
- mise à jour du composant vulnérable ;
- purge des caches ;
- renouvellement des mots de passe et secrets applicatifs ;
- contrôle des employés et administrateurs PrestaShop ;
- contrôle des clés API et webservices ;
- contrôle FTP, SFTP et SSH ;
- contrôle des tâches cron et autres mécanismes de persistance ;
- analyse des accès à la base de données ;
- nouveau scan malware après nettoyage ;
- surveillance renforcée des accès au Back-Office.
Une CVE qu’il ne faut plus considérer comme théorique
Dans l’incident étudié, plusieurs éléments convergent :
Version vulnérable : ps_facetedsearch 3.8.0
+
activité spécifique sur ps_facetedsearch
+
POST successifs
+
apparition immédiate de fichiers PHP exécutables
+
commandes système
+
dépôt de webshells supplémentaires
+
tentatives d'accès à MySQL
La chronologie observée est extrêmement cohérente avec le scénario technique décrit pour CVE-2026-54159.
Une boutique utilisant encore une version comprise entre 3.0.0 et 4.0.3 doit donc être mise à jour sans attendre.
Mettre à jour ne suffit pas toujours
Si une boutique est restée plusieurs semaines avec une version vulnérable, installer aujourd’hui la version 4.0.4 corrige le point d’entrée.
Mais cela ne permet pas de savoir si le serveur a déjà été compromis.
Il faut alors rechercher les traces laissées avant la mise à jour : nouveaux fichiers PHP, webshells, accès inhabituels, modifications, connexions à la base et comptes administrateurs inconnus.
Un contrôle relativement rapide des fichiers et journaux permet déjà d’identifier de nombreux signaux.
Conclusion
Cet incident montre pourquoi la sécurité d’une boutique PrestaShop ne peut pas reposer sur une seule protection.
Module vulnérable
↓
Exploitation très probable de CVE-2026-54159
↓
Remote Code Execution
↓
Webshell
↓
Installation de nouvelles portes d'entrée
↓
Adminer
↓
Tentatives d'accès MySQL
↓
Persistance pendant plusieurs jours
↓
Détection par Phenix Malware Scanner
↓
Analyse forensic des logs Apache
↓
Identification de la CVE
↓
Mise à jour 3.8.0 → 4.0.4
↓
Nettoyage et rotation des secrets
↓
Installation de SmallGuard Lite
↓
Blocage et journalisation de nouvelles tentatives
Premier enseignement : maintenir les modules à jour. Un WAF ne remplacera jamais le correctif d’une vulnérabilité connue.
Deuxième enseignement : une mise à jour ne permet pas de savoir si l’exploitation a déjà eu lieu. Lorsqu’une boutique est restée exposée, une analyse des fichiers et des logs est nécessaire.
Troisième enseignement : conserver les logs. Sans les journaux Apache, nous aurions découvert plusieurs fichiers suspects. Grâce aux logs, nous avons pu reconstruire l’incident presque seconde par seconde.
Il y a une différence importante entre supprimer un fichier malveillant et comprendre réellement comment un serveur a été compromis.
Vous utilisez PrestaShop ?
Vérifiez dès maintenant la version du module
Navigation à facettes / ps_facetedsearch.
Toute version comprise entre 3.0.0 et 4.0.3 doit être mise à jour vers 4.0.4 ou une version ultérieure corrigée.
En cas de doute sur une boutique qui est restée exposée, un contrôle des fichiers PHP récemment créés, de la version des modules et des journaux Apache permet d’effectuer une première vérification rapidement.
Sources
PrestaShop / GitHub Security Advisory :
GHSA-m5f5-28qr-9g9r — CVE-2026-54159
PrestaShop Project :
Security update for the Faceted Search module




