Sécuriser la base de données : wp-config et accès MySQL
Quand on parle de “sécurité” sur un site WordPress, on pense vite au pare-feu, au thème, au plugin de cache, ou à la politique de mots de passe. Pourtant, une grande partie des incidents côté serveur vient d’un angle mort classique: la base de données. Si quelqu’un obtient les identifiants MySQL, WordPress devient une simple interface, et le reste n’est plus qu’une question de minutes.
Dans la pratique, la surface de risque la plus immédiate se trouve dans wp-config.php. C’est le fichier qui contient le nom de la base, l’utilisateur, et surtout le secret qui permet de s’y connecter. Un mauvais contrôle d’accès au fichier, des droits trop larges sur le compte MySQL, ou une configuration trop permissive sur le serveur peuvent transformer une “petite erreur” en incident majeur. Voici comment aborder ça de manière réaliste, avec des décisions pragmatiques et des garde-fous.
Comprendre ce que wp-config.php révèle réellement
wp-config.php n’est pas juste un fichier de configuration. C’est un bloc d’accès. WordPress l’utilise au démarrage pour établir une connexion à MySQL, et il s’attend à retrouver des paramètres précis:
le nom de la base (DB_NAME) l’utilisateur (DB_USER) le mot de passe (DB_PASSWORD) l’hôte MySQL (DB_HOST), parfois “localhost”, parfois une adresse distante parfois un préfixe de tables ($table_prefix)
Le point sensible, c’est DB_PASSWORD. Même si l’attaquant ne connaît pas le reste, il peut tenter des actions à partir de cet identifiant. Et si, en plus, l’utilisateur MySQL a des droits trop larges, il peut faire bien plus que lire. Dans un scénario réaliste, on voit souvent deux variations: soit l’attaquant obtient le fichier wp-config.php via une mauvaise configuration d’accès au serveur, soit il récupère les secrets en lisant les traces d’un déploiement, en exploitant une fuite de sauvegarde, ou via une exposition accidentelle d’un répertoire.
Ce qui rend le sujet délicat, c’est que beaucoup d’hébergeurs “font le travail” sur le plan de la sécurité globale, mais la configuration WordPress reste chez vous. Un plugin qui modifie des droits, une restauration qui remet les permissions d’origine, un changement de propriétaire après migration, et vous perdez tout le bénéfice d’un durcissement antérieur.
Premier réflexe: protéger l’accès au fichier de configuration
Sur un site WordPress installé correctement, wp-config.php doit être lisible uniquement par le processus PHP côté serveur. Dans la plupart des cas, il ne devrait jamais être servi comme contenu HTTP. Si ce fichier devient accessible depuis l’extérieur, la sécurité s’effondre, même si votre mot de passe MySQL est long.
Concrètement, vous voulez empêcher deux chemins:
L’accès direct via URL (par exemple /wp-config.php) L’accès via mauvaise résolution de fichiers ou configuration de réécriture (par exemple des règles qui exposent un répertoire)
Sur Apache, on utilise souvent une règle qui refuse l’accès à wp-config.php. Sur Nginx, on s’appuie sur les directives de blocage côté serveur. Les détails dépendent de votre environnement, mais l’idée est constante: empêcher la lecture HTTP du fichier, pas seulement “le cacher”.
C’est là que je recommande d’aller au-delà des “valeurs par défaut”. J’ai déjà vu des sites qui avaient un wp-config.php protégé, puis un changement de configuration (ou une montée de version du reverse proxy) a cassé la règle. Résultat: le fichier n’était plus protégé, sans que personne ne s’en rende compte car aucun test automatique ne vérifiait l’impossibilité d’y accéder.
Vérifier les permissions système: un détail qui coûte cher quand il est raté
Même si vous bloquez l’accès HTTP, il reste la question des permissions sur le système de fichiers. Sur un hébergement standard, le fichier doit être suffisamment restreint pour que seul l’utilisateur qui exécute PHP puisse le lire.
Ce point est souvent mal interprété. Beaucoup pensent qu’il suffit de mettre wp-config.php en lecture seule pour tout le monde. En réalité, “lecture seule” ne veut pas dire “protégé” si l’accès est large, et “droits restrictifs” ne veut pas dire “tout est sécurisé” si le pare-feu ou la configuration serveur exposent le contenu.
Sans imposer une valeur unique valable https://gardewp.fr/securite-wordpress/ https://gardewp.fr/securite-wordpress/ partout, une logique s’impose:
wp-config.php doit être lisible par l’utilisateur PHP (ou le groupe approprié) il doit être non lisible par les autres comptes non nécessaires le répertoire WordPress et les fichiers associés ne doivent pas être trop ouverts
Je fais aussi une remarque opérationnelle: après une migration, on perd parfois l’héritage des droits. Si vous utilisez Git, un pipeline CI, ou des scripts de déploiement, attention aux options de copie qui réappliquent les permissions “au hasard”. Le bon réflexe consiste à comparer les droits avant et après migration, pas uniquement “sur le moment”.
Hôte MySQL: localhost vaut mieux que “une machine quelconque”
Le paramètre DB_HOST semble anodin, mais il influence directement l’exposition réseau du service MySQL. Sur la plupart des hébergements classiques, MySQL tourne localement pour le compte du site, et DB_HOST est de type localhost ou une valeur interne.
Quand DB_HOST pointe vers une adresse distante, vous ajoutez des dépendances réseau: routage, pare-feu, règles d’accès, et compatibilité TLS. Dans ce cas, l’utilisateur MySQL doit également être autorisé depuis l’hôte d’origine. Dans le monde réel, c’est souvent là que les mauvaises configurations se voient: un compte MySQL autorisé depuis trop de machines, ou depuis un subnet complet “par commodité”.
Le trade-off est simple: si vous devez accéder à distance, il faut durcir la règle d’autorisation MySQL côté serveur de base de données et documenter précisément quelles adresses peuvent se connecter. Si vous ne le faites pas, vous finissez par “ouvrir large” pour régler un problème de connexion, puis oublier cette ouverture.
Droits MySQL: le secret ne suffit pas, il faut aussi le périmètre
Même avec un mot de passe robuste, le compte MySQL utilisé par WordPress ne devrait pas être un compte administrateur. Il doit être limité à ce qui permet réellement à WordPress de fonctionner.
Pourquoi ? Parce que WordPress, dans son usage normal, a besoin de:
lire et écrire dans les tables de la base créer certaines structures lors d’installations, mises à jour, ou opérations spécifiques gérer des tables liées aux plugins et aux thèmes, selon les cas
Mais il n’a pas besoin d’accéder à d’autres bases “au hasard”, ni d’avoir des droits globalement élevés. Un compte trop puissant augmente l’impact d’une compromission, et la plupart des attaques suivent une progression: d’abord obtenir les identifiants, puis utiliser les droits pour élargir l’accès.
Si vous gérez vos bases vous-même, la bonne approche consiste à créer un utilisateur dédié à chaque site, limiter son accès à la base concernée, et éviter les privilèges génériques. Sur un hébergement mutualisé, vous n’avez pas toujours la main fine sur les privilèges, mais vous pouvez souvent au moins choisir un user unique par site et vérifier ce que l’interface d’hébergement demande comme droits.
Cas concrets: ce qui se passe quand wp-config.php est compromis
Imaginons un incident. Supposons que quelqu’un récupère wp-config.php et donc DB_PASSWORD. Le premier effet n’est pas forcément “destruction”. Souvent, l’attaquant commence par:
tester la connexion vérifier les tables WordPress et celles des plugins repérer l’existence de comptes administrateurs modifier des éléments qui assurent la persistance (par exemple des options WordPress, ou des insertions dans des zones sensibles)
Le danger augmente si le compte MySQL a des droits étendus. Un compte limité à la base du site réduit la capacité d’exfiltration, et limite la portée si l’attaquant ne trouve que ce qu’il faut dans la base.
À l’inverse, si vous changez uniquement le mot de passe MySQL dans wp-config.php sans réexaminer les droits, vous “stoppez l’accès” mais vous ne savez pas si l’attaquant a déjà pu modifier des éléments de persistance. En incident response, on ne se contente pas de révoquer, on vérifie. Cette logique s’applique aussi ici: vous changez, mais vous auditez ce qui a peut-être été altéré.
Gérer le risque au quotidien: rotation et hygiène des identifiants
Beaucoup de sites ne changent jamais DB_PASSWORD. Cela n’est pas catastrophique en soi si tout est bien sécurisé, mais c’est risqué en cas de fuite potentielle. Or les fuites arrivent par des chemins multiples: sauvegardes mal protégées, dépôts de configuration partagés, exports, accès à des machines de maintenance, ou erreurs lors d’un “restore” sur un environnement de test.
Une approche pragmatique consiste à prévoir une rotation de mot de passe dans trois cas:
suspicion de divulgation (fuite, incident, accès anormal) migration vers un nouvel hébergement ou nouvelle base refonte de la chaîne de déploiement (nouvel outil, nouveaux serveurs, nouveaux comptes)
Le trade-off, c’est la maintenance. Changer DB_PASSWORD nécessite une mise à jour de wp-config.php, puis de vérifier que WordPress et les jobs associés fonctionnent toujours. Mais mieux vaut une petite intervention planifiée qu’une urgence après coup.
Sécuriser l’accès MySQL côté réseau: réduire la surface avant de “durcir le mot de passe”
Le mot de passe seul est une barrière. Si MySQL est accessible depuis trop d’endroits, l’attaquant n’a même pas besoin de deviner, il teste. Cela devient un problème de surface d’attaque, pas uniquement de secret.
Sans entrer dans des commandes qui dépendent trop de votre stack, l’idée est simple:
n’ouvrez pas MySQL sur Internet limitez l’accès aux adresses nécessaires appliquez des règles réseau cohérentes avec DB_HOST contrôlez les connexions entrantes et les tentatives anormales si vous avez les outils
Dans un contexte d’hébergement classique, cette couche est souvent gérée par l’infrastructure. Dans des configurations plus “artisanales”, c’est vous qui devez faire attention. J’ai vu des setups où MySQL écoutait sur toutes les interfaces par défaut, puis “on a corrigé plus tard”. Plus tard n’arrive presque jamais, surtout quand le site fonctionne.
Revenir à WordPress: confirmer que la configuration ne fuit pas ailleurs
Une fois wp-config.php protégé et MySQL limité, il reste une question qui revient souvent en audit: la configuration fuit-elle ailleurs que dans le fichier ?
Quelques exemples typiques:
captures et journaux qui contiennent des erreurs avec le contexte de connexion sauvegardes stockées dans un répertoire accessible environnements de staging accessibles publiquement fichiers “temporaires” générés pendant un déploiement
Je privilégie toujours une règle de bon sens: aucune sauvegarde ou archive ne doit être exposée via HTTP. Même si l’archive ne contient pas le mot de passe en clair, elle contient souvent des traces qui accélèrent l’attaque.
Et si vous utilisez un outil de sauvegarde automatique, assurez-vous que la logique de stockage respecte le principe du moindre privilège. Un stockage trop ouvert équivaut à rendre public votre wp-config.php, même si le fichier source n’est jamais accessible.
Une mini méthode de vérification (rapide, mais utile)
Avant de modifier quoi que ce soit, faites un diagnostic minimal. L’objectif n’est pas de “scanner” comme un outil de pentest, c’est de vérifier vos hypothèses de base.
Essayez d’accéder à wp-config.php via HTTP et confirmez que l’accès est refusé. Vérifiez que les permissions de wp-config.php permettent la lecture par PHP, mais pas par des comptes non nécessaires. Contrôlez la valeur de DB_HOST et confirmez qu’elle correspond à une configuration réseau raisonnable. Assurez-vous que l’utilisateur MySQL est dédié au site et limité à la base concernée. Testez une fois après toute modification WordPress, notamment l’accès à l’administration et la mise en cache si vous l’utilisez.
Cette séquence prend peu de temps, mais elle évite des changements en aveugle. Elle m’a déjà évité des situations où un blocage serveur était en place, mais cassé par un changement de reverse proxy, ou où une migration avait réinitialisé les droits sans prévenir.
Choisir des paramètres robustes dans wp-config.php sans casser WordPress
wp-config.php ne doit pas devenir un terrain de bricolage. Chaque modification doit avoir un bénéfice clair. Pour la partie “sécurité”, la priorité reste:
ne pas exposer le fichier utiliser un mot de passe MySQL long et unique limiter les droits côté MySQL
Au-delà, certains choisissent d’ajouter des constantes ou de modifier des comportements. Là, je conseille la prudence: plus vous modifiez le fichier de façon personnalisée, plus vous augmentez la probabilité d’un conflit lors d’une mise à jour WordPress ou d’un plugin. Sur un site professionnel, la stabilité compte autant que la sécurité.
Si vous devez inclure des ajustements, gardez-les simples, documentez-les dans votre procédure interne, et testez sur un environnement de staging dès que c’est possible. L’erreur courante consiste à “gagner du temps” en modifiant directement sur la production, puis à passer une journée à comprendre pourquoi une connexion échoue.
L’approche “pro” pour les droits et les identifiants, sans surcomplexifier
Les meilleurs résultats viennent rarement d’une seule mesure. C’est l’empilement cohérent: accès fichier bloqué, droits MySQL limités, réseau restreint, rotation planifiée.
Voici une règle pratique que j’applique dans les projets WordPress à enjeu:
un utilisateur MySQL dédié par site, avec un périmètre réduit un mot de passe MySQL généré, unique, et stocké hors du dépôt de code un fichier wp-config.php non exposé et avec des permissions cohérentes un contrôle des sauvegardes et des environnements (staging inclus)
Si vous travaillez en équipe, ajoutez une contrainte de process: personne ne doit “copier-coller” des secrets depuis une capture ou un ticket. Une fois que vous avez des secrets dans un ticket, ils vivent trop longtemps. Préférez une gestion de secrets ou, à défaut, une procédure interne sécurisée.
Deux erreurs fréquentes qui neutralisent les efforts
Il y a des pièges qui reviennent, surtout quand on intervient après plusieurs mains.
1) Le compte MySQL utilisé par WordPress est trop puissant. Même si wp-config.php est protégé, un compromis d’identifiants devient alors beaucoup plus grave.
2) Les permissions système et les règles d’accès HTTP ne sont pas testées après migration. Le site fonctionne, donc on pense que tout est bon. Jusqu’au jour où quelqu’un utilise un chemin d’URL ou une configuration différente, et la protection ne s’applique plus comme avant.
Ces deux erreurs ne sont pas spectaculaires. Elles sont banales, et ce sont souvent les banales qui coûtent le plus cher.
Checklist d’hygiène à garder en tête (et à répéter)
Voici une liste courte, volontairement pragmatique, pour garder l’essentiel sans se perdre.
Bloquer l’accès HTTP à wp-config.php et vérifier que la protection tient après chaque changement d’infrastructure. Utiliser un utilisateur MySQL dédié, limité à la base WordPress du site. Mettre un mot de passe MySQL long, unique, et le changer en cas de suspicion de fuite. Réserver l’accès réseau à MySQL aux seules adresses nécessaires. S’assurer que les sauvegardes et archives ne sont jamais exposées via HTTP, et contrôller les environnements de test. Réagir si vous suspectez une fuite des identifiants MySQL
Si vous avez un doute raisonnable, une réaction structurée vaut mieux qu’un panique-réaction. La logique générale consiste à:
révoquer l’accès en changeant DB_PASSWORD (et en mettant à jour wp-config.php) vérifier si des modifications ont eu lieu dans la base (options, utilisateurs, traces liées aux plugins) vérifier l’intégrité WordPress (fichiers modifiés, thèmes, plugins, uploads) revoir ce qui a pu exposer wp-config.php (permissions, règles serveur, sauvegardes, accès staging)
Le point important: si vous ne faites qu’un changement de mot de passe, vous pourriez laisser en place une persistance déjà installée côté WordPress. L’attaquant n’est pas obligé de “garder” l’accès si le site lui-même a été modifié pour revenir. D’où l’intérêt d’une vérification après la rotation.
Petits détails qui font une vraie différence dans les projets WordPress professionnels
Sur des sites gérés sérieusement, j’ai vu plusieurs pratiques qui rendent le risque plus gérable:
séparer la production et le staging, avec des identifiants distincts et une base distincte éviter de réutiliser les mêmes secrets entre environnements surveiller les logs et les alertes d’erreurs liées à la base (ça ne prouve pas une attaque, mais ça donne un signal) limiter les accès aux serveurs et aux sauvegardes, car une fuite “humainement” évitable arrive très souvent par là
On peut avoir une configuration serveur propre et un wp-config.php protégé, mais si une archive de sauvegarde traîne sur un espace web ou si l’accès à la base est partagé inutilement, tout le reste devient cosmétique.
Le sujet n’est donc pas seulement “écrire une ligne de sécurité”. C’est un ensemble de disciplines.
Ce qu’il faut retenir
Sécuriser la base de données avec wp-config.php et l’accès MySQL, ce n’est pas une checklist magique. C’est un raisonnement en couches, avec un point focal: empêcher la divulgation du fichier et limiter l’impact d’une éventuelle divulgation.
Quand vous protégez wp-config.php, que vous assurez des permissions cohérentes, que vous utilisez un compte MySQL dédié et limité, et que vous restreignez l’accès réseau, vous réduisez drastiquement la probabilité d’un incident. Et si malgré tout un identifiant fuit, vous transformez l’attaque potentielle en événement beaucoup moins destructeur.
C’est exactement l’esprit d’une sécurité site WordPress professionnel: des mesures concrètes, vérifiables, qui tiennent dans le temps, surtout après les migrations et les changements d’infrastructure.