Si vous avez déjà vu un “PHP Warning: failed to open stream: Permission denied” ou un “Allowed memory size exhausted” juste après une tentative d’intrusion, il y a de fortes chances que l’attaquant cherchait un fichier précis : wp-config.php.
Sur WordPress 6.9.4 (avril 2026), wp-config.php reste le point de concentration des secrets (clés de cookies), du cheminement vers la base, et de plusieurs interrupteurs de sécurité. Mal configuré, il ne “rend pas WordPress vulnérable” à lui seul… mais il rend une compromission plus facile, plus silencieuse, et plus durable.
La menace
Si un attaquant obtient un accès en lecture à wp-config.php, il récupère typiquement :
- Les identifiants de base de données (DB_NAME, DB_USER, DB_PASSWORD, DB_HOST). Selon l’hébergement, ça suffit à lire/modifier des tables, injecter un admin, ou déposer une backdoor via des options.
- Les clés et salts d’authentification (AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY et leurs SALTs). Ça permet de révoquer des sessions… mais si l’attaquant les vole, il peut aussi forger des cookies sur certains scénarios de vol de session (selon le contexte et l’accès aux cookies).
- Des constantes “debug” (WP_DEBUG, WP_DEBUG_LOG, SCRIPT_DEBUG) qui, mal utilisées, finissent par exposer des chemins serveur, des requêtes SQL, ou des secrets dans des logs accessibles.
- Des paramètres de durcissement (DISALLOW_FILE_EDIT, DISALLOW_FILE_MODS, FORCE_SSL_ADMIN, etc.). Un attaquant qui peut écrire dans
wp-config.phppeut les neutraliser pour faciliter la persistance.
Si un attaquant obtient un accès en écriture à wp-config.php, c’est souvent “game over” :
- il peut exécuter du PHP arbitraire (puisque
wp-config.phpest inclus très tôt) ; - désactiver des protections ;
- rediriger la base, injecter du code dans des options, ou installer une porte dérobée qui survit aux mises à jour.
La fréquence réelle varie selon les sources et votre niche, mais, dans mon expérience de dépannage, les incidents impliquant wp-config.php sont rarement la cause initiale. C’est plutôt la “récompense” après un premier accès (plugin vulnérable, identifiants FTP volés, compte admin compromis). Le bon réflexe : durcir wp-config.php pour limiter l’impact et rendre l’attaque bruyante (détectable) au lieu de silencieuse.
Résumé rapide
- Ne stockez pas de secrets “en dur” dans le thème ou un plugin : centralisez dans
wp-config.phpou, mieux, dans des variables d’environnement si vous maîtrisez le serveur. - Verrouillez l’édition et l’installation via
DISALLOW_FILE_EDITet, selon votre contexte,DISALLOW_FILE_MODS. - Forcez HTTPS côté admin si votre proxy/CDN ne le fait pas déjà correctement (
FORCE_SSL_ADMIN+ configuration des en-têtes). - Désactivez l’affichage d’erreurs en production (WP_DEBUG false) et sécurisez les logs.
- Protégez l’accès HTTP à
wp-config.phpau niveau serveur (.htaccess / Nginx) même si WordPress ne l’expose pas “normalement”. - Changez les clés/salts après tout incident : cela invalide les sessions.
Code vulnérable — ce qu’il ne faut PAS faire
Voici un mauvais exemple que je vois encore sur des sites bricolés à partir de vieux tutos : wp-config.php devient un fourre-tout, avec debug permanent, logs exposés, et des “raccourcis” dangereux.
<?php
// ⚠️ Exemple volontairement dangereux : ne copiez pas ce fichier.
// Debug activé en prod : fuite d'infos (chemins, requêtes, erreurs PHP)
define('WP_DEBUG', true);
define('WP_DEBUG_DISPLAY', true);
// Log dans un répertoire web accessible
define('WP_DEBUG_LOG', true); // /wp-content/debug.log (souvent téléchargeable)
// Autoriser l'éditeur de fichiers dans l'admin : vecteur de persistance si un compte est compromis
define('DISALLOW_FILE_EDIT', false);
// Clés faibles / réutilisées (ou pire : laissées par défaut)
define('AUTH_KEY', '123');
define('SECURE_AUTH_KEY', '123');
define('LOGGED_IN_KEY', '123');
define('NONCE_KEY', '123');
define('AUTH_SALT', '123');
define('SECURE_AUTH_SALT', '123');
define('LOGGED_IN_SALT', '123');
define('NONCE_SALT', '123');
// "Astuce" dangereuse : accepter un mode admin via paramètre URL (porte dérobée)
if (!empty($_GET['enable_admin'])) {
define('DISALLOW_FILE_MODS', false);
}
// Connexion DB en clair (normal), mais avec un utilisateur trop privilégié (ex: root)
define('DB_NAME', 'wp');
define('DB_USER', 'root');
define('DB_PASSWORD', 'root');
define('DB_HOST', 'localhost');
require_once __DIR__ . '/wp-settings.php';
Comment l’attaque fonctionne (sans “mode d’emploi” d’exploitation)
Le problème vient de trois points :
- Debug en production : une simple erreur PHP (souvent déclenchée par un paramètre inattendu, une requête malformée, un plugin instable) peut afficher des chemins, versions, ou fragments de configuration. Sur certains stacks, des logs deviennent accessibles via HTTP.
- Éditeur de fichiers : si un attaquant obtient un compte admin (phishing, mot de passe réutilisé, cookie volé), il peut injecter du PHP directement depuis l’admin, sans FTP.
- Backdoor “conditionnelle” : le snippet qui lit
$_GETdanswp-config.phpest une catastrophe. J’ai souvent croisé ce type de “toggle” ajouté pour dépanner vite… puis oublié. C’est exactement le genre de chose qu’un attaquant cherche.
Code sécurisé — la bonne implémentation
Objectif : garder wp-config.php prévisible, verrouillé, et peu bavard en production. Le fichier ne doit pas contenir de logique métier, ni dépendre de paramètres web. Il doit définir des constantes, point.
Base solide (WordPress 6.9.4+, PHP 8.1+)
<?php
/**
* wp-config.php (exemple durci)
* Compatible WordPress 6.9.4+ / PHP 8.1+
*/
/* 1) Base de données : utilisateur SQL dédié, droits minimaux */
define('DB_NAME', 'votre_db');
define('DB_USER', 'wp_user_limite');
define('DB_PASSWORD', 'changez_ce_mdp');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
/* 2) Clés et salts : uniques, longues, aléatoires */
define('AUTH_KEY', 'mettez_une_chaine_longue_aleatoire');
define('SECURE_AUTH_KEY', 'mettez_une_chaine_longue_aleatoire');
define('LOGGED_IN_KEY', 'mettez_une_chaine_longue_aleatoire');
define('NONCE_KEY', 'mettez_une_chaine_longue_aleatoire');
define('AUTH_SALT', 'mettez_une_chaine_longue_aleatoire');
define('SECURE_AUTH_SALT', 'mettez_une_chaine_longue_aleatoire');
define('LOGGED_IN_SALT', 'mettez_une_chaine_longue_aleatoire');
define('NONCE_SALT', 'mettez_une_chaine_longue_aleatoire');
/* 3) HTTPS admin : utile si votre proxy/CDN est correctement configuré */
define('FORCE_SSL_ADMIN', true);
/* 4) Verrouillage de l'admin (réduit l'impact d'un compte compromis) */
define('DISALLOW_FILE_EDIT', true);
/**
* Si votre flux de mise à jour est géré (CI/CD, Git, hébergeur managé),
* vous pouvez bloquer les modifications (plugins/thèmes/maj) depuis l'admin.
* ⚠️ À activer seulement si vous êtes sûr de pouvoir déployer autrement.
*/
// define('DISALLOW_FILE_MODS', true);
/* 5) Debug : silencieux en production */
define('WP_DEBUG', false);
define('WP_DEBUG_DISPLAY', false);
/**
* Log : si vous en avez besoin, envoyez-le hors du webroot.
* Exemple : /var/log/wordpress/site-debug.log (à créer et protéger côté serveur)
*/
// define('WP_DEBUG_LOG', '/var/log/wordpress/site-debug.log');
/* 6) Limiter la rétention des révisions (réduit surface et taille DB) */
define('WP_POST_REVISIONS', 20);
/* 7) Désactiver l'exécution de PHP dans /wp-content/uploads (côté serveur aussi) */
define('ALLOW_UNFILTERED_UPLOADS', false);
/* 8) Chemin absolu */
if (!defined('ABSPATH')) {
define('ABSPATH', __DIR__ . '/');
}
require_once ABSPATH . 'wp-settings.php';
Explication “simple” : ce que chaque mesure vous apporte
- Clés/salts fortes : rendent les cookies et nonces imprévisibles. Si vous les changez, vous forcez la déconnexion globale (utile après incident).
- FORCE_SSL_ADMIN : évite qu’un admin se connecte en HTTP si un mauvais lien ou une config bancale le permet.
- DISALLOW_FILE_EDIT : supprime un des chemins les plus courts vers l’injection de code.
- WP_DEBUG à false : empêche d’exposer des informations sensibles aux visiteurs.
- Logs hors webroot : même si un log contient des infos sensibles, il n’est pas téléchargeable via le navigateur.
Explication technique : pièges et edge cases réels
1) FORCE_SSL_ADMIN et les proxies/CDN
Sur des sites derrière Cloudflare, un load balancer, ou certains hébergeurs, WordPress peut “voir” une connexion HTTP côté backend alors que le visiteur est en HTTPS. Résultat : boucles de redirection, cookies mal marqués, ou admin inaccessible.
Avant d’activer FORCE_SSL_ADMIN, vérifiez que votre stack envoie correctement les en-têtes (ex: X-Forwarded-Proto: https) et que PHP/serveur les interprète. Si vous avez déjà eu des boucles, corrigez d’abord côté serveur (section “Configuration serveur”).
2) DISALLOW_FILE_MODS : utile, mais pas “magique”
DISALLOW_FILE_MODS bloque l’installation/édition de plugins et thèmes depuis l’admin, et empêche aussi les mises à jour auto via l’UI. Sur un site géré “à la main” (Elementor/Divi/Avada installés via l’admin), activer ça sans plan de déploiement est le meilleur moyen de se retrouver coincé le jour où une CVE sort.
3) WP_DEBUG_LOG et fuites de logs
Le piège classique : activer WP_DEBUG_LOG et oublier. Sur beaucoup d’hébergements mutualisés, /wp-content/debug.log finit par être lisible si :
- une règle serveur est trop permissive ;
- un plugin de cache expose des fichiers ;
- une mauvaise config MIME/permissions traîne.
Si vous devez logger, loggez hors webroot et verrouillez les permissions (idéalement 640 avec un owner correct).
4) “Copier-coller au mauvais endroit”
Je vois souvent des constantes ajoutées après require_once ABSPATH . 'wp-settings.php';. À cet endroit, c’est trop tard : WordPress est déjà chargé, et la constante ne changera rien (ou déclenchera des warnings). Toutes les constantes doivent être définies avant ce require_once.
Option avancée : secrets via variables d’environnement
Si vous avez la main sur le serveur (ou un hébergeur managé qui expose des env vars), vous pouvez sortir les secrets du fichier. Ça ne rend pas le site invulnérable, mais ça réduit le risque si un backup de code fuit.
<?php
// Exemple : récupérer les secrets depuis l'environnement (si défini).
// ⚠️ Ne cassez pas votre site : prévoyez un fallback clair.
$db_name = getenv('WP_DB_NAME');
$db_user = getenv('WP_DB_USER');
$db_pass = getenv('WP_DB_PASSWORD');
$db_host = getenv('WP_DB_HOST') ?: 'localhost';
if (!$db_name || !$db_user || !$db_pass) {
// En production, je préfère échouer explicitement plutôt que de continuer avec des valeurs vides.
// Vous pouvez aussi prévoir un fallback statique si votre infra ne gère pas les env vars.
die('Configuration serveur incomplète (variables d’environnement DB manquantes).');
}
define('DB_NAME', $db_name);
define('DB_USER', $db_user);
define('DB_PASSWORD', $db_pass);
define('DB_HOST', $db_host);
Piège réaliste : certains plugins de “snippets” ou thèmes enfants ne doivent jamais toucher à wp-config.php. Si vous testez ce changement, faites-le d’abord en staging, avec un plan de rollback (restaurer le fichier original).
Les constantes de sécurité à connaître (et quand les utiliser)
Voici celles que je rencontre le plus souvent en audit WordPress. Je vous donne l’usage, le bénéfice, et les pièges.
| Constante | But | Recommandation (prod) | Piège fréquent |
|---|---|---|---|
DISALLOW_FILE_EDIT |
Désactive l’éditeur de fichiers dans l’admin | true | Oublié sur des sites “sensibles” (e-commerce, sites à fort trafic) |
DISALLOW_FILE_MODS |
Bloque installation/maj/édition de plugins & thèmes via admin | Selon workflow | Activé sans CI/CD : plus de mises à jour de sécurité possibles |
FORCE_SSL_ADMIN |
Force HTTPS sur l’admin | true (si proxy OK) | Boucle de redirection si proxy/CDN mal configuré |
WP_DEBUG |
Mode debug global | false | Laissé à true après un dépannage |
WP_DEBUG_DISPLAY |
Affiche les erreurs à l’écran | false | Affiche des chemins et infos sensibles |
WP_DEBUG_LOG |
Log des erreurs | Chemin hors webroot | debug.log exposé dans /wp-content/ |
SCRIPT_DEBUG |
Charge versions non-minifiées (dev) | false | Ralentit inutilement, bruit dans le cache |
WP_AUTO_UPDATE_CORE |
Contrôle des mises à jour core | Garder défaut / managé | Désactivé “pour être tranquille” → core obsolète |
AUTOMATIC_UPDATER_DISABLED |
Désactive l’auto-updater | Éviter | Bloque les correctifs de sécurité silencieusement |
WP_CACHE |
Active un cache drop-in | Selon plugin | Conflits après migration, cache non vidé |
WP_POST_REVISIONS |
Limite le nombre de révisions | 10–50 | Mis à 0 sans réfléchir (perte d’historique utile) |
EMPTY_TRASH_DAYS |
Durée avant purge corbeille | 7–30 | Mis à 0 (suppression immédiate) sur sites éditoriaux |
Docs officielles utiles : wp-config.php sur developer.wordpress.org et Editing wp-config.php (WordPress.org).
Configuration serveur
wp-config.php se protège surtout en dehors de WordPress. Si quelqu’un arrive à télécharger ce fichier via HTTP, votre problème est déjà au niveau serveur.
Apache (.htaccess) : bloquer l’accès à wp-config.php
# À placer dans le .htaccess à la racine WordPress (Apache)
<Files "wp-config.php">
Require all denied
</Files>
Sur certains hébergements, les règles sont déjà présentes. Je l’ajoute quand même si je reprends un site “historique”. Ça ne casse rien et ça évite les surprises.
Apache (.htaccess) : protéger debug.log si vous l’utilisez
# Bloquer l'accès web aux logs dans wp-content
<Files "debug.log">
Require all denied
</Files>
Nginx : bloquer l’accès à wp-config.php (et aux fichiers sensibles)
# Dans le server block Nginx
location = /wp-config.php {
deny all;
return 404;
}
# Optionnel : bloquer des fichiers cachés et fichiers de config
location ~* /(readme.html|license.txt|.env|composer.(json|lock)|phpunit.xml) {
deny all;
return 404;
}
Permissions fichier (Linux) : le minimum raisonnable
Le bon réglage dépend de votre modèle PHP (PHP-FPM, suPHP, etc.). Mais en pratique :
- wp-config.php : 640 ou 600 (si le user PHP peut le lire). Évitez 644.
- propriétaire : l’utilisateur du process PHP ou un utilisateur du même groupe, selon votre stack.
# Exemple : permissions strictes (à adapter)
chmod 640 wp-config.php
Piège : “je mets 444 pour être sûr”. Ça peut casser les mises à jour automatiques, certains systèmes de déploiement, et compliquer un incident (vous ne pourrez plus écrire rapidement les nouvelles clés). Préférez un modèle cohérent plutôt que “ultra verrouillé au hasard”.
Headers HTTP : renforcer la surface (sans casser l’admin)
Ce n’est pas directement wp-config.php, mais ça réduit les vecteurs d’exploitation (XSS, clickjacking) qui finissent souvent par du vol de session admin.
Apache (si mod_headers est dispo) :
# Exemples de headers de base
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Content-Security-Policy est excellent, mais délicat sur WordPress (plugins, page builders). Sur Divi 5 / Elementor / Avada, une CSP trop stricte casse souvent l’éditeur. Je la déploie plutôt en mode Report-Only d’abord, puis j’ajuste.
Vérifier si votre site est vulnérable
Vous cherchez ici des signaux concrets : constantes dangereuses, logs exposés, et modifications suspectes de wp-config.php.
WP-CLI : vérifier l’état du debug et des constantes
WP-CLI ne lit pas toutes les constantes “en direct” facilement, mais il est très utile pour repérer des symptômes (plugins suspects, utilisateurs admin inattendus, options modifiées).
# Lister les admins (chercher un compte inconnu)
wp user list --role=administrator --fields=ID,user_login,user_email,registered
# Voir les plugins actifs (chercher un plugin inconnu ou "mu-plugin" suspect)
wp plugin list --status=active
# Inspecter les MU-plugins (souvent utilisés pour persister)
wp plugin list --must-use
Vérifier l’intégrité des fichiers core
Si wp-config.php est modifié, l’attaquant modifie souvent aussi un fichier core ou un drop-in. WP-CLI permet de vérifier le core (pas vos plugins/thèmes).
# Vérification des checksums du core (marche si WordPress.org standard)
wp core verify-checksums
Sur le serveur : détecter une modification récente de wp-config.php
# Date de modification
ls -la wp-config.php
# Chercher du code suspect (eval, base64, gzinflate, etc.)
grep -nE "eval(|base64_decode(|gzinflate(|str_rot13(" wp-config.php
Ne partez pas du principe que “base64 = hack”. J’ai déjà vu des hébergeurs injecter des wrappers, et des plugins ajouter des constantes. Mais dans wp-config.php, c’est extrêmement rare d’avoir besoin de ça : traitez-le comme suspect.
Logs : ce qu’il faut chercher
- Accès répétés à
/wp-config.php,/.env,/wp-content/debug.log,/xmlrpc.php,/wp-json/endpoints inhabituels. - Pics de 403/404 sur des fichiers sensibles (souvent du scanning automatisé).
- POST anormaux sur
/wp-admin/admin-ajax.phpou sur des endpoints REST si un plugin expose une action vulnérable.
Tableau de diagnostic (symptômes concrets)
| Symptôme | Cause probable | Vérification | Solution |
|---|---|---|---|
Fichier /wp-content/debug.log téléchargeable |
Règles serveur permissives + WP_DEBUG_LOG activé | Tester en navigation (sans partager l’URL), vérifier .htaccess/Nginx | Bloquer l’accès + déplacer le log hors webroot + désactiver debug en prod |
| Boucle de redirection vers /wp-admin | FORCE_SSL_ADMIN + proxy mal déclaré | Vérifier en-têtes X-Forwarded-Proto / config CDN |
Corriger config proxy, puis activer FORCE_SSL_ADMIN |
| Admins inconnus | Compromission compte / DB | wp user list, logs de connexion, table wp_users |
Supprimer comptes, réinitialiser mots de passe, auditer plugins |
Modif récente de wp-config.php sans intervention |
Accès FTP/SSH volé ou faille RCE via plugin | ls -la, historique déploiement, logs SFTP |
Rotation secrets, nettoyage, durcissement, restauration propre |
Erreurs de sécurité fréquentes
| Erreur | Risque | Solution | |
|---|---|---|---|
Activer WP_DEBUG sur un site public “temporairement” |
Fuite d’infos (chemins, versions, warnings), logs exploitables | WP_DEBUG false en prod, logs hors webroot, process de debug en staging |
|
Ajouter une constante après wp-settings.php |
La constante ne sert à rien, comportement incohérent | Définir toutes les constantes avant le require_once |
|
Utiliser un snippet trouvé en ligne avec une logique basée sur $_GET/$_POST dans wp-config.php |
Porte dérobée involontaire | Interdire toute logique web dans wp-config.php |
|
Laisser DISALLOW_FILE_EDIT à false |
Injection de code via admin si compte compromis | Mettre à true | |
Activer DISALLOW_FILE_MODS sans plan de mise à jour |
Vous ne patcherez plus vite en cas de faille | Activer seulement si vous avez CI/CD ou hébergeur managé | |
Permissions 777 sur wp-content “pour que ça marche” |
Écriture facile pour un attaquant (upload + exécution) | Corriger owner/group, droits minimaux, désactiver PHP dans uploads | |
| Tester directement en production sans sauvegarde | White screen (fatal error), indisponibilité | Staging + sauvegarde + plan de rollback du fichier | |
Oublier un point-virgule dans wp-config.php |
Fatal error au bootstrap (site KO) | Éditer avec un éditeur qui valide PHP, déployer via Git si possible | |
| Copier une vieille recommandation incompatible (PHP 7.x) | Warnings/fatals sous PHP 8.1+ | Vérifier compatibilité, lire les docs actuelles, tester | |
| Conflit cache après modification (cookies/HTTPS) | Redirections, admin instable | Vider cache plugin/CDN/navigateur après changement de SSL ou cookies | Purger caches + vérifier config proxy |
Checklist de durcissement
- Bloquer l’accès HTTP à
/wp-config.php(Apache/Nginx). - Permissions correctes sur
wp-config.php(600/640 selon stack), pas de 777 nulle part. - Clés/salts uniques (pas de valeurs courtes, pas de réutilisation entre sites).
- WP_DEBUG = false en production ;
WP_DEBUG_DISPLAY = false. - Si log nécessaire : WP_DEBUG_LOG vers un chemin hors webroot + accès restreint.
- DISALLOW_FILE_EDIT = true.
- FORCE_SSL_ADMIN = true si votre HTTPS/proxy est sain (sinon corriger d’abord).
- Limiter l’utilisateur SQL : pas de root, droits minimaux sur la DB WordPress.
- Backups chiffrés et test de restauration (un backup non testés est un espoir, pas un plan).
- Mettre à jour core/plugins/thèmes rapidement (surtout Divi 5, Elementor, Avada et leurs add-ons).
Que faire si le site est déjà compromis ?
Si vous suspectez une compromission, votre priorité n’est pas “durcir” : c’est stopper l’hémorragie, préserver les preuves, puis repartir proprement.
- Mettre le site en maintenance (au minimum restreindre /wp-admin via IP ou mot de passe HTTP).
- Faire une sauvegarde complète (fichiers + base) avant toute suppression. Elle servira à l’analyse.
- Changer immédiatement :
- mots de passe WordPress (tous les admins) ;
- mots de passe FTP/SFTP/SSH ;
- mots de passe base de données ;
- clés/salts dans
wp-config.php(déconnexion globale).
- Vérifier
wp-config.php:- chercher du code ajouté (tout ce qui n’est pas des
define(), ou des includes suspects) ; - comparer avec une version saine (Git, backup connu).
- chercher du code ajouté (tout ce qui n’est pas des
- Vérifier l’intégrité du core :
wp core verify-checksums;- réinstaller le core depuis une source officielle si doute.
- Auditer les plugins/thèmes :
- désactiver ceux inconnus ;
- mettre à jour ;
- supprimer ceux abandonnés.
- Inspecter les MU-plugins et
wp-content(uploads inclus) : c’est une zone de persistance fréquente. - Rechercher des admins injectés + vérifier les rôles/capacités modifiés.
- Analyser les logs (web + auth + SFTP) pour comprendre le point d’entrée. Sans ça, vous serez re-compromis.
- Remettre en ligne seulement après validation : admin OK, pas de fichiers suspects, pas de redirections, pas de tâches cron inconnues.
Si vous gérez un site à fort enjeu, ne jouez pas au héros : faites intervenir un spécialiste IR (incident response). Une mauvaise “désinfection” laisse souvent une backdoor invisible.
Conseils de maintenance et compatibilité
Page builders (Divi 5, Elementor, Avada) : ce qui change en pratique
- DISALLOW_FILE_EDIT ne gêne pas Divi/Elementor/Avada : ces builders n’en ont pas besoin. Vous pouvez l’activer sans crainte.
- DISALLOW_FILE_MODS peut gêner les workflows où un éditeur installe des add-ons depuis l’admin (très courant avec Elementor). Si vous l’activez, prévoyez une procédure de déploiement (staging + déploiement contrôlé).
- CSP / headers : une politique trop stricte casse souvent l’éditeur visuel (iframes, inline scripts). Déployez progressivement.
Performance et SEO
- Déplacer les logs hors webroot et désactiver l’affichage d’erreurs évite des réponses HTML “polluées” par des warnings (mauvais pour l’UX et parfois indexées par des bots).
- Un
wp-config.phppropre réduit le risque de fatals au bootstrap, donc moins d’indisponibilités (et moins de “soft 500” qui plombent le crawl).
Process de changement sûr
- Faites vos modifications sur staging d’abord.
- Gardez une copie de
wp-config.php(hors webroot) avant édition. - Après changement SSL/cookies : purgez cache plugin + cache CDN + cache navigateur. J’ai souvent vu des gens “débugger” 30 minutes un problème qui était juste un cache de redirection.
Ressources
- Developer Resources — wp-config.php
- WordPress.org — Editing wp-config.php
- Developer Resources — Security (Advanced Administration)
- WP-CLI — Commandes
- Code source WordPress (GitHub mirror)
- WordPress Core Trac
- PHP.net — getenv()
FAQ
Dois-je déplacer wp-config.php au-dessus du webroot ?
Si votre hébergement le permet, oui : WordPress sait charger un wp-config.php situé un niveau au-dessus de la racine d’installation. Ça réduit le risque d’exposition via une mauvaise config web. Testez en staging : certains hébergeurs ont des structures de répertoires particulières.
Changer les clés/salts casse-t-il quelque chose ?
Ça déconnecte tout le monde (sessions invalidées). C’est attendu. Sur des sites avec beaucoup d’éditeurs, prévenez l’équipe. Après compromission, c’est une action standard.
Quelle longueur pour les clés ?
Longue et aléatoire. Évitez les phrases, évitez tout ce qui est mémorisable. Utilisez un générateur de secrets fiable, puis stockez-les dans un gestionnaire de mots de passe. La doc WordPress propose un service officiel pour générer des clés : api.wordpress.org/secret-key/1.1/salt.
DISALLOW_FILE_EDIT suffit-il à empêcher l’injection de code ?
Non. Ça retire un vecteur très pratique pour un attaquant qui a déjà un admin. Mais si un plugin vulnérable permet l’upload/exécution, ou si les identifiants FTP sont compromis, l’attaquant peut quand même écrire des fichiers.
Dois-je activer DISALLOW_FILE_MODS sur tous les sites ?
Seulement si votre processus de mise à jour est maîtrisé (déploiement via Git, CI/CD, ou hébergeur managé). Sinon vous vous privez du patch rapide, ce qui est souvent pire.
WP_DEBUG_LOG est-il “dangereux” ?
Il l’est si le log est accessible via HTTP ou s’il contient des secrets. En pratique : loggez hors webroot, restreignez les permissions, et activez-le uniquement pendant une fenêtre de diagnostic.
FORCE_SSL_ADMIN est-il encore utile si j’ai un CDN ?
Oui, mais seulement si votre CDN/proxy est correctement configuré. Sinon, vous aurez des boucles. Vérifiez d’abord la chaîne HTTPS (certificat, redirections, en-têtes proxy).
Est-ce que wp-config.php doit contenir des règles de sécurité “intelligentes” (IF, conditions) ?
Non, évitez. Plus vous ajoutez de logique, plus vous créez des cas limites et des portes involontaires. Gardez-le déclaratif : des define(), rien d’autre (à part le chargement final).
Pourquoi éviter l’utilisateur SQL “root” ?
Parce qu’en cas de fuite, l’impact explose. Un utilisateur SQL dédié, limité à la base WordPress et aux droits nécessaires, réduit les dégâts (et limite les mouvements latéraux sur le serveur DB).
Je suis sur un hébergement mutualisé, je ne peux pas modifier Nginx/Apache. Je fais quoi ?
Commencez par ce que vous contrôlez : permissions, clés/salts, debug off, DISALLOW_FILE_EDIT, mises à jour rapides. Ensuite, demandez au support l’ajout des règles de blocage (beaucoup acceptent) ou migrez vers un hébergeur qui permet un minimum de durcissement.
Après durcissement, l’éditeur Elementor/Divi ne charge plus : c’est lié ?
Le plus fréquent : une règle de sécurité serveur trop agressive (CSP, X-Frame-Options mal réglé, WAF), ou un cache qui sert une ancienne redirection HTTP→HTTPS. Désactivez temporairement les nouveaux headers, purgez les caches, puis réactivez progressivement.