Le WordPress d'aujourd'hui, décodé pour les développeurs

Sécurité

Un rançongiciel visait 40 sites médias : les permissions qui ont limité

Une tentative de chiffrement de fichiers sur un serveur hébergeant plusieurs rédactions a été stoppée net grâce à des permissions par utilisateur PHP correctement isolées. Retour sur l'incident.

Par Clément Hadrot • 16 mai 2022 • 4 min de lecture • Aucun commentaire
Un rançongiciel visait 40 sites médias : les permissions qui ont limité

Un constat technique a mis la puce à l’oreille de l’équipe d’astreinte, un dimanche matin : des centaines de fichiers .locked apparaissant soudainement dans le dossier wp-content/uploads d’un des sites hébergés sur un serveur mutualisé regroupant quarante rédactions locales indépendantes, chacune disposant de son propre site WordPress mais partageant la même machine physique.

Le scénario redouté pour ce type d’infrastructure mutualisée, un rançongiciel qui chiffre l’ensemble des fichiers accessibles depuis un point d’entrée compromis, semblait en train de se réaliser. Ce qui a limité l’ampleur des dégâts n’était pas un outil de détection sophistiqué, mais une décision d’architecture prise des mois plus tôt lors du provisionnement du serveur.

Symptôme : un chiffrement de fichiers en cours

L’analyse a montré que le processus malveillant avait obtenu l’exécution de code PHP sur l’un des quarante sites, très probablement via une extension obsolète installée sur ce site précis, puis avait entrepris de parcourir récursivement le système de fichiers pour chiffrer tout contenu accessible en écriture, en commençant par les dossiers de médias, historiquement les plus volumineux et donc les plus rentables à rançonner.

Sur une infrastructure mutualisée sans isolation stricte entre sites, un tel processus aurait pu, en théorie, atteindre l’ensemble des quarante installations WordPress hébergées sur la même machine, dès lors que le processus PHP compromis disposait des mêmes droits d’écriture que n’importe quel autre site du serveur.

Diagnostic : pourquoi le chiffrement s’est arrêté à trois sites

Le serveur avait été configuré avec un pool PHP-FPM distinct par site, chacun exécuté sous un utilisateur système Unix dédié, avec des permissions de fichiers strictement limitées au répertoire propre à ce site. Le processus compromis, exécuté sous l’identité de l’utilisateur système associé au site touché initialement, ne disposait donc d’aucun droit d’écriture sur les répertoires appartenant aux trente-neuf autres sites, malgré leur présence sur la même machine physique.

Le chiffrement s’est donc arrêté aux frontières du système de fichiers accessibles à cet utilisateur précis, touchant en tout trois sites qui partageaient par ailleurs, pour des raisons historiques de migration, le même utilisateur système que le site initialement compromis, une configuration héritée qui a depuis été corrigée pour ces trois cas restants.

L'essentiel à retenir : Un compte compromis ne doit jamais pouvoir écrire hors de son propre site ; php-fpm par pool isolé limite mécaniquement la casse ; Le journal d'accès révèle souvent le point d'entrée initial

Ce que cette isolation a concrètement empêché

Sans cette isolation par utilisateur, l’incident aurait vraisemblablement touché l’ensemble des quarante sites hébergés, avec un temps de restauration et un coût opérationnel sans commune mesure avec celui réellement observé. La configuration retenue au provisionnement du serveur suit un principe simple : chaque site dispose de son propre pool PHP-FPM, défini dans un fichier de configuration dédié, avec un utilisateur et un groupe Unix propres, et des permissions de fichiers refusant explicitement tout accès en écriture en dehors du répertoire du site concerné.

; /etc/php/8.1/fpm/pool.d/site-rennes-actu.conf
[site-rennes-actu]
user = site-rennes-actu
group = site-rennes-actu
listen = /run/php/site-rennes-actu.sock
listen.owner = www-data
listen.group = www-data
php_admin_value[open_basedir] = /var/www/site-rennes-actu:/tmp

La directive open_basedir ajoute une seconde couche de restriction au niveau de PHP lui-même, indépendante des permissions du système de fichiers, ce qui limite la casse même dans l’hypothèse où une mauvaise configuration système laisserait passer un accès qui ne devrait pas l’être.

Restauration et point d’entrée initial

Les trois sites touchés ont été restaurés depuis les sauvegardes de la nuit précédente, avec une perte de données limitée aux quelques heures séparant la dernière sauvegarde de la détection de l’incident. L’analyse des journaux d’accès du site initialement compromis a permis d’identifier une extension de galerie photo obsolète, non mise à jour depuis plus d’un an, comme point d’entrée le plus probable, confirmée ensuite par la publication ultérieure d’une faille connue affectant cette version précise de l’extension.

En résumé

Ce n’est pas un pare-feu ni un scanner de malware qui a limité cet incident à trois sites sur quarante, mais une décision d’architecture prise en amont : isoler chaque site derrière son propre utilisateur système et son propre pool PHP-FPM, de sorte qu’une compromission reste, par construction, contenue à son périmètre d’origine. Sur une infrastructure mutualisée, cette isolation constitue une protection plus déterminante que la plupart des outils de détection réactifs.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi