Une boutique en ligne présente un profil de risque particulier : elle détient des données personnelles, des historiques de commandes, parfois des identifiants de paiement, et elle constitue un point d'entrée intéressant pour un attaquant qui cherche moins à la dégrader qu'à s'en servir. La sécurisation d'une boutique WooCommerce ne se résume pas à installer une extension de sécurité, qui traite surtout des symptômes. Elle repose sur quatre chantiers concrets, les droits sur les fichiers, la gestion des comptes, les clés d'accès programmatique et la journalisation, chacun demandant quelques heures et produisant un effet durable.

Les droits sur les fichiers

C'est le premier chantier parce qu'il est le plus mal réglé sur les installations que nous reprenons, et parce qu'il conditionne la portée d'une compromission. Un attaquant qui obtient un accès limité ne peut pas grand chose si les droits sont corrects, et prend le contrôle complet s'ils sont laxistes. Ce point s'inscrit dans la démarche générale décrite dans notre article sur la manière de mener un audit de sécurité WordPress.

Les valeurs attendues

La règle générale est simple : les dossiers en 755, les fichiers en 644, le fichier de configuration en 640 ou plus restrictif. Aucun fichier ne doit être en 777, valeur que l'on trouve pourtant régulièrement, posée pour résoudre un problème d'envoi de médias et jamais remise en place. Un fichier accessible en écriture par n'importe quel utilisateur du serveur, sur un hébergement mutualisé, est modifiable par le voisin de palier autant que par un attaquant. La correction se fait en une commande, et il vaut mieux la rejouer périodiquement, une manipulation d'urgence remettant régulièrement des droits trop ouverts sur un dossier isolé.

Le propriétaire compte autant que les droits

Les fichiers doivent appartenir à l'utilisateur sous lequel tourne le serveur web, ou à un utilisateur distinct dont ce dernier fait partie du groupe. Une configuration où le serveur web est propriétaire de l'ensemble permet à tout code exécuté par lui de modifier n'importe quel fichier, ce qui est exactement ce qu'exploite une injection réussie. Séparer le propriétaire du processus d'exécution est la mesure structurante de ce chantier.

Le dossier d'envois, cas particulier

Le dossier des médias doit être accessible en écriture, ce qui en fait la cible privilégiée pour déposer un fichier exécutable. La parade consiste à interdire l'exécution de code dans ce dossier au niveau de la configuration du serveur, ce qui neutralise l'attaque même si le dépôt réussit. Cette règle tient en trois lignes et fait partie des mesures dont le rapport entre effort et effet est le plus élevé. La même interdiction gagne à être posée sur tout dossier accessible en écriture, y compris ceux créés par des extensions pour leurs propres besoins, que personne ne recense jamais.

Interdire l'accès direct aux fichiers sensibles

Plusieurs fichiers n'ont aucune raison d'être accessibles depuis le web : le fichier de configuration, les fichiers de journaux, les sauvegardes, les fichiers de composition du projet. Leur interdiction explicite est nécessaire, la protection par obscurité ne fonctionnant pas, des robots testant en permanence les chemins connus. Le contrôle se fait en tentant de les récupérer depuis un navigateur, ce qui prend deux minutes. Ce contrôle mérite d'être automatisé et rejoué après chaque changement d'hébergement, une configuration de serveur ne se transportant pas toujours avec les fichiers.

Désactiver l'édition depuis l'administration

WordPress permet par défaut de modifier les fichiers de thème et d'extension depuis le tableau de bord, ce qui transforme tout accès administrateur en exécution de code arbitraire. Cette fonctionnalité n'a aucune utilité en production et se désactive par une constante de configuration. C'est une ligne, et elle referme le chemin le plus direct entre un mot de passe compromis et une prise de contrôle du serveur. La même constante permet aussi d'interdire l'installation d'extensions depuis l'interface, ce qui se justifie sur une boutique dont les livraisons passent par un dépôt.

Le socle qu'on oublie de regarder

Avant les réglages fins, deux éléments pèsent plus lourd que tout le reste et échappent souvent à l'attention parce qu'ils ne se voient pas dans le tableau de bord. Le premier est la version de PHP : une version qui n'est plus maintenue ne reçoit plus de correctifs de sécurité, quelle que soit la fraîcheur du logiciel de commerce posé dessus, et c'est le cas d'un nombre considérable d'hébergements. Le second est l'isolation de l'hébergement : sur un mutualisé mal cloisonné, la compromission d'un site voisin peut suffire à atteindre le vôtre, ce qui ne relève d'aucune mesure applicative. Ces deux points se vérifient en cinq minutes et conditionnent la valeur de tout ce qui suit ; les traiter en dernier revient à poser des serrures sur une porte qui n'a pas de cadre.

Répartition des droits d’accès entre fichiers, comptes et clés d’interface

Comptes, rôles et accès

La majorité des compromissions passent par un accès légitime obtenu illégitimement, plutôt que par une faille technique. Le chantier des comptes est donc au moins aussi important que celui du code, et il relève autant de l'organisation que de la technique. Il se combine avec la discipline de mise à jour décrite dans notre article sur la manière de surveiller les mises à jour de plugins avec WP-CLI.

Le principe du moindre privilège

Chaque personne doit disposer du rôle le plus faible permettant son travail. Un rédacteur n'a pas besoin d'installer des extensions, un préparateur de commandes n'a pas besoin de modifier les prix, un prestataire ponctuel n'a pas besoin d'un compte permanent. WooCommerce ajoute des rôles dédiés à la gestion de boutique, qui suffisent dans la plupart des cas et évitent la distribution de comptes administrateurs. Sur les installations que nous reprenons, le nombre d'administrateurs dépasse souvent la dizaine sans que personne ne sache dire pourquoi. Le simple fait de poser la question à chaque compte, en demandant quelle action précise justifie ce niveau de droits, ramène ce nombre à deux ou trois dans la plupart des structures.

Revoir les comptes régulièrement

Les comptes s'accumulent : anciens salariés, prestataires partis, comptes de test, comptes créés par des extensions. Une revue trimestrielle, avec suppression ou rétrogradation de tout compte dont l'usage n'est pas justifié, prend une demi heure. La suppression doit se faire avec attribution des contenus à un autre compte plutôt qu'avec effacement, afin de ne pas perdre l'historique des modifications. Cette revue est aussi le moment de vérifier les adresses électroniques associées aux comptes restants, une adresse d'entreprise disparue rendant impossible toute récupération d'accès.

L'authentification à deux facteurs

C'est la mesure la plus efficace contre le vol d'identifiants, et elle devrait être obligatoire pour tout compte disposant de droits d'administration ou d'accès aux commandes. Plusieurs extensions la fournissent correctement. Le point de vigilance est la procédure de récupération : elle doit exister, être documentée, et ne pas constituer elle même une faiblesse, notamment quand elle repose sur une adresse électronique dont l'accès n'est pas lui même protégé. Les codes de secours doivent être générés à l'activation et conservés hors ligne, faute de quoi la mesure protège le site jusqu'au jour où elle en interdit l'accès à son propriétaire.

Protéger la page de connexion

La page de connexion subit des tentatives permanentes, et un mot de passe faible finit par céder. Trois mesures se combinent : une limitation du nombre de tentatives par adresse, un délai croissant après échec, et une politique de mots de passe réellement appliquée. Déplacer l'adresse de la page de connexion ne protège de rien de sérieux mais réduit le bruit dans les journaux, ce qui a une utilité pratique quand on les lit. Le blocage doit porter sur l'adresse d'origine et non sur le compte visé, faute de quoi il devient trivial de verrouiller le compte d'un administrateur en échouant volontairement à s'y connecter.

Les comptes clients

Les comptes des clients méritent le même soin, car ils donnent accès à un historique de commandes et à des adresses. Ils sont rarement protégés par une authentification renforcée, ce qui est acceptable, mais doivent au minimum bénéficier de la limitation des tentatives et d'une vérification de la robustesse du mot de passe. Une brèche sur un compte client isolé ne compromet pas la boutique, mais constitue une fuite de données personnelles à part entière, avec les obligations de notification qui l'accompagnent.

Mesure Effort Ce qu'elle empêche
Interdire l'exécution dans le dossier des médias Quelques minutes Exploitation d'un fichier déposé
Désactiver l'éditeur de fichiers Une ligne Exécution de code depuis un compte volé
Authentification à deux facteurs Une heure Réutilisation d'identifiants dérobés
Revue trimestrielle des comptes Trente minutes Persistance d'accès obsolètes
Clés d'interface limitées en lecture Quelques minutes Modification du catalogue par un tiers
Journalisation des actions sensibles Deux heures Rien, mais permet de comprendre

Les sauvegardes, qui font partie de la sécurité

La sauvegarde n'est pas une mesure de prévention mais elle décide entièrement de ce que coûte un incident, et elle est trop souvent traitée comme un sujet d'exploitation séparé. Trois exigences la rendent réellement utile. Elle doit être hors du serveur sauvegardé, faute de quoi un accès complet permet de la supprimer en même temps que le site. Elle doit couvrir plusieurs dates, une compromission découverte au bout de trois semaines rendant inutile une sauvegarde de la veille, qui contient déjà le problème. Elle doit enfin être restaurée à titre d'essai au moins une fois par an, sur un environnement séparé, seule manière de savoir qu'elle fonctionne. Une sauvegarde contenant des données personnelles doit par ailleurs être chiffrée et son accès restreint, au même titre que la base qu'elle copie.

Les clés d'accès programmatique

WooCommerce expose une interface de programmation qui permet de lire et d'écrire le catalogue, les commandes et les clients. C'est une fonctionnalité indispensable pour les connexions à un logiciel de gestion, et c'est aussi une porte d'entrée dont la surveillance est presque toujours négligée.

Une clé par usage, jamais partagée

Chaque intégration doit disposer de sa propre clé, nommée d'après son usage. Une clé unique partagée entre trois outils interdit de la révoquer sans tout casser, et rend impossible d'attribuer une action à son auteur. La création d'une clé par usage coûte une minute et transforme un incident potentiel en opération de révocation ciblée. La clé secrète n'étant affichée qu'une fois à la création, elle doit être transmise par un canal sûr et jamais par courriel en clair, où elle restera lisible pendant des années.

Choisir le niveau de droits juste

Une clé peut être limitée à la lecture, ce qui suffit à la grande majorité des intégrations : export vers un comparateur, synchronisation d'un tableau de bord, alimentation d'un outil d'analyse. Seules les intégrations qui écrivent réellement, un logiciel de gestion mettant à jour les stocks par exemple, ont besoin de droits d'écriture. Le réflexe consistant à tout créer en lecture et écriture par confort double inutilement la surface de risque. La restriction du droit se double utilement d'une restriction d'origine quand l'hébergement le permet, une clé de synchronisation n'ayant aucune raison d'être utilisable depuis n'importe quelle adresse du monde.

Faire tourner et révoquer

Une clé doit être remplacée périodiquement, et immédiatement lors du départ d'un prestataire ou d'un changement d'outil. Cela suppose de savoir où chaque clé est utilisée, information qui doit être notée au moment de la création et non reconstituée dans l'urgence. Une clé dont personne ne sait à quoi elle sert doit être désactivée plutôt que conservée par précaution, la désactivation étant réversible en quelques secondes.

Surveiller l'usage

Les appels à l'interface laissent des traces dans les journaux du serveur, avec l'adresse d'origine et le point d'accès sollicité. Un relevé mensuel des clés réellement utilisées, comparé à la liste des clés existantes, fait apparaître celles qui ne servent plus. Un pic d'appels inhabituel, ou des appels depuis une adresse nouvelle, méritent une vérification immédiate. Ce relevé est aussi le seul moyen de découvrir qu'une intégration abandonnée continue d'interroger la boutique plusieurs fois par minute, ce qui est fréquent et coûte des ressources pour rien.

Points d'entrée constatés lors de compromissions de boutiques en ligne
Identifiants d'administration réutilisés
31 %
Extension vulnérable non mise à jour
27 %
Fichier déposé dans le dossier des médias
17 %
Clé d'interface exposée ou partagée
14 %
Accès serveur mal cloisonné
11 %

Répartition constatée lors d'interventions correctives sur des boutiques compromises. Les deux premiers postes ne relèvent d'aucune faille du logiciel de commerce lui même.

Journaliser pour pouvoir comprendre

Aucune des mesures précédentes ne garantit qu'il ne se passera rien. Ce qui distingue un incident maîtrisé d'un incident subi, c'est la capacité à savoir ce qui s'est passé, ce qui suppose d'avoir consigné les bonnes choses avant.

Ce qu'il faut consigner

Six familles d'événements couvrent l'essentiel : les connexions réussies et échouées avec leur origine, les changements de rôle et créations de comptes, les installations et activations d'extensions, les modifications de réglages sensibles comme les moyens de paiement, les créations et révocations de clés, et les modifications de commandes après paiement. Chacun doit être enregistré avec sa date, son auteur et son adresse d'origine. Plusieurs extensions de journalisation d'activité font ce travail correctement, et il vaut mieux en installer une que d'écrire ce mécanisme soi même, à condition de vérifier qu'elle écrit ailleurs que dans la base qu'un attaquant pourrait modifier.

Conserver assez longtemps

Une compromission est découverte en moyenne plusieurs semaines après son début, et des journaux conservés sept jours ne servent alors à rien. Une conservation de soixante à quatre vingt dix jours est un minimum raisonnable, et elle doit se faire hors de la machine surveillée, un attaquant disposant d'un accès suffisant commençant en général par effacer ses traces. L'expédition des journaux vers un service externe, ou simplement leur copie quotidienne vers un espace de sauvegarde, suffit à rendre cet effacement inopérant.

Rendre les journaux exploitables

Un journal que personne ne lit ne sert qu'après coup, ce qui est déjà beaucoup, mais quelques alertes ciblées lui donnent une valeur préventive : création d'un compte administrateur, activation d'une extension, modification d'un moyen de paiement, création d'une clé d'interface. Ces quatre événements sont rares et leur survenue non planifiée justifie une notification immédiate. Le réglage doit rester à ce niveau de rareté : ajouter les connexions réussies à la liste des alertes produit des dizaines de messages par jour et fait cesser la lecture de toutes les autres. Cette approche complète la supervision générale décrite dans notre article sur la manière de surveiller un WordPress en production.

Préparer la réaction

Le dernier travail est d'écrire, avant l'incident, la marche à suivre : qui prévenir, comment isoler le site, où sont les sauvegardes, quels mots de passe et clés changer en priorité, et comment prévenir les personnes concernées si des données personnelles sont touchées. Cette note d'une page, relue une fois par an, est ce qui fait la différence entre une journée de gestion ordonnée et une semaine d'improvisation. Elle doit exister ailleurs que sur le site lui même, qui peut précisément être inaccessible au moment où l'on en a besoin. Elle doit également indiquer les coordonnées de l'hébergeur et du prestataire de paiement, deux interlocuteurs que l'on cherche toujours dans l'urgence. Elle doit enfin être conservée hors du site, imprimée ou déposée chez un tiers, une procédure de reprise stockée sur le serveur qu'elle est censée sauver n'ayant évidemment aucune valeur le jour de l'incident.