écrits/blog/2026/05
Blog16 mai 2026·6 min

Audit d'extensions Magento : détecter une backdoor en 30 minutes

Avril 2026 : 31 plugins WordPress rachetés sur Flippa, backdoor poussée 8 mois plus tard. Même TTP côté Magento. Voici l'audit DIY en 30 minutes.

En avril 2026, des attaquants ont racheté 31 plugins WordPress légitimes sur Flippa, ont laissé le code dormir huit mois, puis ont poussé une mise à jour vérolée via les commits SVN officiels. Jusqu'à 400 000 sites se sont retrouvés avec une backdoor PHP active — installée à travers le canal de mise à jour normal, signée par le bon "auteur", validée par WordPress.org.

Cette attaque n'est pas spécifique à WordPress. Le même schéma — racheter un module, attendre, pousser une mise à jour piégée — fonctionne tel quel sur Magento. Le marketplace Adobe, les modules Tigren / MGS / Meetanshi backdoorés en avril 2025 (500 à 1 000 boutiques touchées, dont une multinationale à 40 milliards USD de CA), les copies "nulled" téléchargées sur les forums : la chaîne d'approvisionnement des extensions est aujourd'hui le vecteur n°1 de compromission d'une boutique Magento qui tient à jour son cœur applicatif.

Bonne nouvelle : si vous avez un accès SSH à votre boutique, vous pouvez auditer l'intégralité de vos extensions en 30 minutes, en lignes de commande. Cet article vous donne la procédure, pas à pas. À la fin, vous saurez :

  • Quelles extensions sont installées, et qui les édite
  • Lesquelles présentent des signatures de backdoor connues
  • Si du PHP suspect a été déposé dans vendor/ ou app/code/ récemment
  • Si un compte admin fantôme a été créé
  • Si du JavaScript exfiltre vos paiements

Pourquoi les extensions sont devenues le vecteur n°1

Trois schémas se sont normalisés depuis 2024 :

  1. L'éditeur abandonne. Le module reste en composer.json, plus personne ne le maintient. La première CVE découverte est exploitée pendant des mois avant qu'un mainteneur ne réagisse — ou jamais.
  2. L'éditeur revend. Un développeur indépendant cède son module sur Flippa, Acquire, ou en marketplace. Le nouvel acquéreur a un accès commit légitime. Il pousse une mise à jour bénigne, attend (huit mois pour la campagne WordPress d'avril 2026), puis injecte le payload. Aucun signal de phishing, aucun fork suspect : c'est votre éditeur qui pousse.
  3. La copie "nulled". Téléchargée sur wpnull24, gpldl, des forums Telegram, ou un canal Discord. 90 % de ces copies portent au moins un webshell, un injecteur de spam SEO, ou un skimmer de carte. Endémique chez les agences MENA qui veulent éviter les frais de licence.

Les trois schémas convergent sur le même point : votre vendor/ contient du code exécutable en production qui n'a pas été audité par vous, signé par une chaîne de confiance que vous ne contrôlez plus.

L'audit en 30 minutes — pas à pas

Prérequis : accès SSH à la racine de la boutique (typiquement /var/www/html), bin/magento exécutable, composer installé.

Étape 1 — Inventorier toutes les extensions (3 min)

cd /var/www/html
 
# Tous les modules connus par Magento (actifs ET désactivés)
bin/magento module:status
 
# Détail composer : éditeur, version, source
composer show --installed | grep -iE "^(magento|adobe|tigren|mgs|meetanshi|amasty|mageplaza|webkul|landofcoder|aheadworks|wyomind)"
 
# Liste des modules tiers présents physiquement (hors core Adobe)
ls -la app/code/ 2>/dev/null
ls -la vendor/ | grep -vE "^(magento|adobe|composer|symfony|laminas|psr|monolog|guzzle|phpunit|webonyx|tedivm|ramsey|graphql|zendframework)"

Notez chaque vendor non-officiel. C'est votre liste de cibles à auditer.

Étape 2 — Vérifier l'authenticité de la source (5 min)

Pour chaque module tiers, vérifiez d'où il vient. Un module "marketplace.adobe.com" est différent d'un module "github.com/inconnu/clone".

# Source réelle de chaque package (URL du dépôt)
composer show vendor/nom-du-module | grep -E "source|dist|name"
 
# Comparer la version installée à la dernière version officielle
composer outdated vendor/nom-du-module
 
# Vérifier la signature du `composer.lock` — toute modification manuelle est suspecte
git log --all -p composer.lock | grep -E "tigren|mgs|meetanshi" | head -50

Drapeau rouge : un dist.url qui pointe vers un domaine inconnu (*.ru, *.tk, IP nue), un name qui ne correspond à aucun package public, une version "1.0.0" datée de 2026 sur un module qui en est officiellement à 4.x.

Étape 3 — Scanner les patterns IOC connus (8 min)

Les backdoors PHP partagent une poignée de signatures. Quatre commandes couvrent 80 % des cas.

# 1. eval + base64_decode — le pattern de webshell classique
grep -rEn "eval\s*\(\s*base64_decode" vendor/ app/code/ 2>/dev/null
 
# 2. gzinflate + base64 — variante obfusquée
grep -rEn "gzinflate\s*\(\s*base64_decode|str_rot13\s*\(\s*base64_decode" vendor/ app/code/ 2>/dev/null
 
# 3. preg_replace avec modificateur /e — exécution de code via regex (banni depuis PHP 7 mais réapparaît dans le code injecté)
grep -rEn "preg_replace\s*\(\s*['\"][^'\"]*/[a-z]*e[a-z]*['\"]" vendor/ app/code/ 2>/dev/null
 
# 4. Backdoors connues Tigren / MGS / Meetanshi — pattern documenté par Sansec (avril 2025)
grep -rE "License\.php|registration\.php" vendor/ | grep -iE "tigren|mgs|meetanshi"
 
# 5. Variables superglobales servies à eval — schéma "shell HTTP"
grep -rEn "eval\s*\(\s*\\\$_(GET|POST|REQUEST|COOKIE|SERVER)" vendor/ app/code/ pub/ 2>/dev/null
 
# 6. assert() avec entrée utilisateur — équivalent eval contourné
grep -rEn "assert\s*\(\s*\\\$_(GET|POST|REQUEST)" vendor/ app/code/ pub/ 2>/dev/null

Tout résultat non vide doit être inspecté ligne par ligne. Un faux positif arrive (rare) ; un vrai positif est une compromission.

Étape 4 — Fichiers modifiés récemment dans vendor/ (3 min)

vendor/ ne devrait changer qu'aux composer install / update. Tout fichier modifié hors de cette fenêtre est anormal.

# Fichiers PHP modifiés dans vendor/ depuis 180 jours
find vendor/ -name "*.php" -mtime -180 -type f -ls | head -50
 
# Comparer aux dates de composer.lock — toute mtime postérieure au dernier `composer install` est suspecte
stat -c "%y %n" composer.lock

Dans pub/media/ et pub/static/ — qui ne doivent jamais contenir de PHP exécutable :

find /var/www/html/pub/media/ /var/www/html/pub/static/ \
  -name "*.php" -o -name "*.phtml" -o -name "*.php7" -o -name "*.phar" 2>/dev/null

Tout retour ici est, par construction, malveillant.

Étape 5 — Comptes admin fantômes (2 min)

# Lister tous les utilisateurs admin Magento
bin/magento admin:user:unlock --help >/dev/null 2>&1 # vérifier que la commande est dispo
 
mysql -u $(grep -A1 '\[default\]' app/etc/env.php | grep -oP "(?<=username' => ')[^']+" | head -1) \
      -p$(grep -oP "(?<=password' => ')[^']+" app/etc/env.php | head -1) \
      -e "SELECT user_id, username, email, created, modified, is_active FROM admin_user ORDER BY created DESC;" \
      $(grep -oP "(?<=dbname' => ')[^']+" app/etc/env.php | head -1)

Chercher : un compte créé en dehors de votre planning de recrutement, un email gmail/protonmail aléatoire, une date de création très récente, un is_active=1 pour un compte que personne ne reconnaît.

Étape 6 — Logs var/log/ et anomalies de session (4 min)

# Connexions admin réussies sur les 30 derniers jours
grep -rE "admin.*login.*success" var/log/ | tail -50
 
# IPs distinctes ayant accédé à /admin
grep -E "/admin" /var/log/nginx/access.log* 2>/dev/null | awk '{print $1}' | sort -u
 
# Patterns de tentatives de scraping CC — accès anormalement fréquents au checkout
grep -E "/checkout/onepage|/rest/V1/carts" /var/log/nginx/access.log* 2>/dev/null \
  | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

Un attaquant qui prépare un skimmer reconnaît la page checkout pour confirmer son injection. Une IP unique avec 200+ hits sur /checkout/onepage en quelques heures est un signal.

Étape 7 — Intégrations REST API non autorisées (3 min)

Les attaquants créent souvent un token API pour persister même si vous changez le mot de passe admin.

mysql -e "SELECT entity_id, name, status, created_at FROM integration ORDER BY created_at DESC;" \
  $(grep -oP "(?<=dbname' => ')[^']+" app/etc/env.php | head -1)
 
# Tokens OAuth actifs
mysql -e "SELECT consumer_id, key, created_at, user_type FROM oauth_token WHERE revoked=0 ORDER BY created_at DESC LIMIT 20;" \
  $(grep -oP "(?<=dbname' => ')[^']+" app/etc/env.php | head -1)

Toute intégration que vous n'avez pas créée est une porte d'entrée persistante.

Étape 8 — JavaScript de checkout (2 min)

Le payload final d'un skimmer Magecart est rarement dans vendor/ — il est injecté en base via core_config_data ou en template via un module compromis.

mysql -e "SELECT path, value FROM core_config_data WHERE value LIKE '%<script%' OR value LIKE '%javascript:%';" \
  $(grep -oP "(?<=dbname' => ')[^']+" app/etc/env.php | head -1)
 
# Tous les domaines tiers servant du JS sur la page checkout
curl -s https://votre-boutique.tld/checkout | grep -oE 'src="https?://[^"]+\.js"' | sort -u

Tout domaine externe que vous ne reconnaissez pas (analytics légitime mis à part) doit être identifié et bloqué via CSP.

Si vous trouvez quelque chose

Ne redémarrez pas le serveur. Vous perdriez la mémoire vive utile à l'analyse forensique.

  1. Isoler : couper l'accès public (firewall sortant + entrant, ou page de maintenance).
  2. Snapshoter : image disque complète + dump RAM si possible.
  3. Notifier : en Tunisie, l'INPDP doit être informée sous 72 h si des données personnelles ont fuité (loi 2004-63). En Arabie saoudite, la SDAIA exige une notification PDPL sous 72 h également (en vigueur depuis le 14 septembre 2024).
  4. Engager un prestataire en réponse à incident — pas votre intégrateur Magento habituel, sauf s'il a une équipe forensique dédiée.
  5. Rotater tous les secrets : MySQL, SMTP, clés API Stripe / PayPal, comptes admin, clés SSH, OAuth integrations.
  6. Restaurer depuis une sauvegarde antérieure à la compromission (vérifiez les mtime de vos backdoors pour dater l'événement) — pas la sauvegarde de la veille.

Prévention : transformer cet audit en pipeline continu

L'audit 30 minutes répond à une question : "est-ce que je suis compromis aujourd'hui ?". Pour ne plus avoir à se la poser :

  • composer audit en CI — bloquant. Toute CVE connue dans vos dépendances casse le build.
  • Politique d'extensions écrite : aucune installation hors marketplace Adobe ou éditeur préapprouvé. Pas de "nulled". Pas de "j'ai trouvé ça sur GitHub".
  • Abonnement Sansec eComscan — scanner Magento spécialisé, payant mais qui détecte les variantes obfusquées que grep rate.
  • Code escrow pour vos modules custom : chaque commit poussé chez vous + chez un tiers (BitBucket / GitLab.com côté client) — l'agence ne peut pas vous prendre en otage si la relation se dégrade.
  • Revue annuelle des extensions : matrice "module, éditeur, dernière maj, CVE ouvertes, alternative". Tout module non maintenu depuis 18 mois doit être remplacé ou retiré.
  • WAF avec règles Magento (Sucuri, Cloudflare Pro+, ou ModSecurity OWASP CRS) : bloque la majorité des tentatives de PolyShell et SessionReaper (CVE-2025-54236) avant qu'elles n'atteignent PHP.
  • Monitoring d'intégrité : tripwire, aide, ou simplement un cron qui compare les checksums de vendor/ et app/code/ à un état de référence et alerte sur diff.

Audit d'extensions Magento par Noqta

L'audit 30 minutes ci-dessus est conçu pour être exécutable par votre équipe technique. Si vous voulez le même travail livré clé en main, avec rapport priorisé, plan de remédiation et accompagnement de la mise en conformité PDPL (KSA) ou loi 2004-63 (Tunisie), c'est ce que nous faisons.

L'audit complet Noqta inclut :

  • Inventaire exhaustif composer.lock + app/code + vendor/
  • Scan IOC étendu (signatures Sansec, patterns obfusqués)
  • Vérification d'intégrité des templates checkout
  • Audit des comptes admin + intégrations REST + tokens OAuth
  • Revue WAF + CSP + en-têtes de sécurité
  • Rapport criticité haute/moyenne/basse + plan d'action 30 / 60 / 90 jours

Tarif et fenêtre d'intervention à valider avec l'équipe selon la taille de votre boutique.

Demander un audit d'extensions Magento

FAQ

L'audit casse-t-il quelque chose ? Non. Toutes les commandes ci-dessus sont en lecture seule (grep, find, mysql -e SELECT, composer show). Aucune ne modifie le code, la configuration ou la base.

Faut-il arrêter la boutique pendant l'audit ? Non. L'audit s'exécute sur la production en charge. Les find peuvent consommer de l'I/O sur de gros volumes — lancer en heures creuses si la boutique est tendue.

Et si on n'a pas d'accès SSH ? Demandez-le à votre hébergeur. Si on vous le refuse, c'est un drapeau rouge sur le contrat lui-même — voir notre dossier sur les risques liés aux fournisseurs IT en MENA.

Magento Open Source vs Adobe Commerce : la méthode change ? Non. La structure vendor/ + app/code/ est identique. Adobe Commerce ajoute des modules cloud qui ne sont pas modifiables, mais le périmètre tiers s'audite exactement de la même façon.

Combien de temps entre la compromission d'un éditeur et l'exploitation ? La campagne WordPress d'avril 2026 a montré 8 mois de dormance. Pour la campagne Magento Tigren / MGS / Meetanshi documentée par Sansec, le code malveillant attendait depuis 2019 et a été activé en avril 2025 — soit 6 ans de dormance. La règle : si vous n'avez jamais audité, vous êtes potentiellement déjà piégé.


Sources publiques : Sansec (Tigren/MGS/Meetanshi backdoor, avril 2025 ; PolyShell mars 2026), Blue Headline (campagne WordPress Flippa avril 2026), Wordfence (La Studio Element Kit, janvier 2026 — 20 000 sites), Adobe APSB25-88 (CVE-2025-54236 SessionReaper), Wiz Research (historique ransomware base de données), Foregenix (Adminer SSRF technical writeup). Réglementation : INPDP Tunisie (loi 2004-63), SDAIA Arabie saoudite (PDPL en vigueur depuis le 14 septembre 2024).