
Audit du .htaccess : pourquoi le site renvoie 500 et quelles règles ne fonctionnent pas
Faites glisser le fichier — l'outil repérera le BOM, les directives mortes, les règles à fort risque d'erreur 500 et les signes d'une intervention extérieure. Le fichier est lu dans votre navigateur et n'est envoyé nulle part.
Le texte a été collé manuellement, le bloc de vérifications sur les octets a donc été ignoré. Pour voir le BOM, les CRLF et les caractères invisibles, déposez le fichier lui-même.
Un .htaccess propre ne guérit pas un piratage. Si le site est compromis, le code malveillant vit dans le PHP et le .htaccess n'en est que la conséquence : le dropper réécrira le fichier quelques minutes après votre nettoyage. L'ordre des opérations est inverse — trouver d'abord le code exécutable, puis remettre de l'ordre dans la configuration.
Le fichier source avec les numéros de ligne apparaîtra ici.
Les lignes comportant des trouvailles sont marquées d'un ! : rouge pour les erreurs, ambre pour les avertissements. Les caractères invisibles et non imprimables sont affichés par un point · — dans le fichier lui-même, il n'y a rien à leur place.
Le nettoyage supprime le BOM, convertit les fins de ligne en LF, retire les caractères non imprimables, remplace les espaces insécables par des espaces ordinaires et ajoute un saut de ligne final. Les directives ne sont pas modifiées. Le fichier est enregistré sous htaccess-clean.txt — renommez-le en .htaccess avant de l'envoyer sur le serveur.
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
C'est exactement ce que WordPress écrit lui-même. Placez vos propres règles au-dessus de la ligne # BEGIN WordPress : tout ce qui se trouve entre les marqueurs est réécrit chaque fois que vous enregistrez les réglages de permaliens.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]
</IfModule>
# END WordPress
Pour un multisite en sous-domaines, le bloc est le même, mais sans le préfixe ^([_0-9a-zA-Z-]+/)? dans les trois dernières règles : RewriteRule ^(wp-(content|admin|includes).*) $1 [L] et RewriteRule ^(.*\.php)$ $1 [L].
Remplacer le bloc ne rétablit pas les permaliens à lui seul : après modification, allez dans Réglages → Permaliens et cliquez sur « Enregistrer » — WordPress vérifiera le bloc et le réécrira si nécessaire.
Le fichier est lu dans votre navigateur — son contenu n'est envoyé nulle part ni enregistré.
Pourquoi un fichier plutôt qu'un texte collé
La cause la plus fréquente d'une erreur 500 après modification de .htaccess n'est pas visible dans le texte. C'est le BOM — trois octets invisibles en début de fichier, ajoutés par le Bloc-notes de Windows lors d'un enregistrement en UTF-8. Apache les considère comme faisant partie de la première directive et ne parvient pas à l'analyser. C'est pourquoi l'outil demande le fichier lui-même : c'est le seul moyen de lire les octets et de voir le BOM, les retours à la ligne de style Windows et les caractères invisibles à l'intérieur des lignes. Deuxième groupe de problèmes : les directives qui ne font rien tout en paraissant opérationnelles. mod_gzip_on relève de la syntaxe d'Apache 1.3 ; sur les serveurs actuels, elle est ignorée en silence, tandis que l'on croit pendant des années que la compression est active. Un bloc ExpiresByType enveloppé dans un test sur mod_headers.c au lieu de mod_expires.c ne fonctionnera pas davantage — et sans indication, cela passe inaperçu. Troisièmement, php_value et php_flag. Ils ne fonctionnent que si PHP est chargé comme module Apache. Sur les hébergements modernes avec PHP-FPM, une telle ligne est soit ignorée, soit renvoie immédiatement une 500. Et un mot à part sur la sécurité : si le fichier contient des règles qui redirigent les visiteurs selon le moteur de recherche d'où ils viennent, ou qui masquent la redirection à l'administrateur, c'est un signe typique de compromission. Mais un .htaccess propre ne guérit pas le piratage : presque toujours, un script PHP réside quelque part dans les fichiers et le réécrira.
