Un htaccess WordPress bien réglé ferme des vecteurs d'attaque entiers, force le HTTPS et pilote le cache navigateur — côté serveur, sans toucher au code du CMS. Le fichier .htaccess est le point de configuration le plus direct d'un site servi par Apache ou LiteSpeed. Encore faut-il savoir quel serveur le lit : Apache et LiteSpeed interprètent le .htaccess à chaque requête, Nginx ne le lit pas du tout et ignore silencieusement ces directives. Le fichier se trouve à la racine de l'installation, à côté de wp-config.php. Règle absolue avant toute modification : en faire une copie. Une seule directive invalide renvoie une erreur 500 sur l'ensemble du site, et le seul retour en arrière fiable est la restauration de la version précédente.
L'essentiel en un coup d'œil
| Question | Réponse courte |
|---|---|
Quel serveur lit le .htaccess ? |
Apache et LiteSpeed oui, à chaque requête ; Nginx non — il l'ignore totalement |
| Où se trouve le fichier ? | À la racine du site, à côté de wp-config.php |
| Avant toute modification ? | Sauvegarder le fichier — une directive invalide = erreur 500 sur tout le site |
| Où placer ses propres règles ? | Hors des marqueurs # BEGIN WordPress / # END WordPress, réécrits automatiquement |
| Déjà géré côté Tomco ? | Compression, cache navigateur et bloc LSCache — inutile de les dupliquer |
Anatomie du htaccess WordPress par défaut
À l'installation, WordPress génère un bloc minimal délimité par deux marqueurs, # BEGIN WordPress et # END WordPress. Il ne contient que la réécriture des permaliens : toute requête qui ne correspond pas à un fichier ou un dossier existant est routée vers index.php.
# BEGIN WordPress
<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
Règle structurante : ne jamais écrire entre ces deux marqueurs. WordPress réécrit l'intégralité du bloc dès qu'un permalien est enregistré dans Réglages → Permaliens, ou lors de certaines mises à jour. Toute ligne ajoutée à l'intérieur disparaît sans avertissement. Les règles personnalisées — sécurité, redirections, cache — se placent au-dessus de # BEGIN WordPress ou en dessous de # END WordPress.
Le serveur lit le fichier de haut en bas, à chaque requête, et applique les directives dans l'ordre rencontré. C'est ce qui rend la position des blocs déterminante, en particulier pour les redirections. Sur l'infrastructure de notre hébergement web, LiteSpeed interprète nativement le .htaccess grâce à sa compatibilité Apache : les règles ci-dessous s'appliquent sans adaptation, là où un environnement Nginx pur exigerait de tout convertir en configuration serveur, suivie d'un rechargement du service.

Règles de sécurité essentielles du htaccess
Ces règles forment le socle de durcissement que le support Tomco fournit à ses clients, partagé ici dans sa version générique. Chacune ferme un accès précis. Elles complètent — sans les remplacer — les mesures applicatives détaillées dans le guide sécuriser WordPress en 2026, dont le .htaccess est l'application concrète côté serveur.
Protéger wp-config.php. Ce fichier contient les identifiants de base de données et les clés de salage. Interdire son accès HTTP bloque toute lecture directe :
# Interdire l'accès direct à wp-config.php
<Files wp-config.php>
Require all denied
</Files>
Require all denied est la syntaxe Apache 2.4 et LiteSpeed (l'ancienne forme Order deny,allow / Deny from all relevait d'Apache 2.2). Le scan de wp-config.php est un vecteur constant : l'infrastructure Tomco en bloque des dizaines de milliers de tentatives par mois.
Bloquer xmlrpc.php. L'interface XML-RPC sert d'amplificateur de force brute (méthode system.multicall, qui teste des centaines d'identifiants en une requête) et de levier de déni de service par pingback. Si aucune application mobile, ni Jetpack, ni pingback n'en dépend, la couper entièrement :
# Bloquer XML-RPC si aucun usage légitime
<Files xmlrpc.php>
Require all denied
</Files>
Interdire l'exécution PHP dans /uploads. Le payload final de nombreuses compromissions est un webshell déposé dans wp-content/uploads. Ce dossier ne doit jamais exécuter de PHP. La règle se place dans un .htaccess distinct, créé dans wp-content/uploads/ :
# wp-content/uploads/.htaccess — bloquer l'exécution de scripts
<FilesMatch "\.(?i:php|phtml|php3|php4|php5|php7|phps)$">
Require all denied
</FilesMatch>
*Masquer les fichiers `.ht` et couper le listing de répertoires.** Ces deux protections figurent déjà dans la plupart des configurations serveur — c'est le cas chez Tomco — mais les inscrire explicitement ne nuit pas sur un hébergement générique :
# Bloquer l'accès aux fichiers .htaccess / .htpasswd
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
# Désactiver l'affichage du contenu des répertoires
Options -Indexes

Le schéma résume l'ordre dans lequel une requête traverse le fichier : redirections d'abord, blocages de sécurité ensuite, règles de cache, puis routage final vers WordPress. Une requête refusée par un Require all denied n'atteint jamais PHP — c'est tout l'intérêt d'un filtrage au niveau serveur, en amont du moteur applicatif.
Limiter les accès aux fichiers sensibles
Au-delà du socle, trois restrictions réduisent encore la surface exposée. Elles supposent un contexte précis : ne les appliquer qu'en connaissance de cause.
Restreindre wp-login.php à une IP fixe. Si l'administration se fait toujours depuis la même adresse (bureau, VPN), verrouiller le formulaire de connexion au niveau serveur écarte la quasi-totalité du brute force avant PHP :
# N'autoriser wp-login.php que depuis une IP de confiance
<Files wp-login.php>
Require ip 203.0.113.42
</Files>
Remplacer 203.0.113.42 par l'adresse réelle. Éviter de protéger tout le dossier /wp-admin par IP : admin-ajax.php y réside et plusieurs plugins l'appellent depuis le front-end public — une restriction trop large casserait des fonctionnalités visiteurs.
Bloquer des user-agents hostiles. Les scanners automatisés s'annoncent fréquemment par un user-agent caractéristique. Les filtrer réduit le bruit dans les logs :
# Bloquer quelques user-agents d'outils de scan
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (nikto|sqlmap|masscan|libwww-perl) [NC]
RewriteRule .* - [F,L]
</IfModule>
Cette liste reste indicative : un user-agent se falsifie en une ligne. Sur l'infrastructure Tomco, le pare-feu applicatif (ModSecurity) absorbe déjà l'essentiel de ce trafic en amont — la règle relève ici du complément, pas de la première ligne de défense.
Protéger wp-includes. Aucun script de wp-includes n'a vocation à être appelé directement. Le motif officiel de durcissement bloque ces accès, à placer hors des marqueurs WordPress :
# Bloquer l'accès direct aux scripts de wp-includes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
Ne pas appliquer ce bloc sur une installation multisite, où il casse des chemins légitimes — la documentation de durcissement WordPress le précise.
Performance : cache navigateur et compression
Deux mécanismes accélèrent le rendu sans plugin : le cache navigateur (mod_expires) indique au navigateur combien de temps conserver chaque type de fichier ; la compression (mod_deflate) réduit le poids transféré du HTML, du CSS et du JavaScript.
Point essentiel pour les clients Tomco : ces deux mécanismes sont déjà actifs par défaut côté serveur. La compression (équivalent LiteSpeed de mod_deflate, Brotli inclus) et les en-têtes de cache navigateur sont appliqués sans configuration. Ajouter les blocs ci-dessous y serait redondant — au mieux sans effet, au pire en conflit avec les en-têtes serveur. Ils restent utiles sur un hébergement Apache générique qui ne les active pas.
# Cache navigateur — REDONDANT chez Tomco (déjà actif côté serveur)
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresDefault "access plus 2 days"
</IfModule>
# Compression — REDONDANT chez Tomco (compression + Brotli déjà actifs)
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE application/rss+xml image/svg+xml
</IfModule>
Ne jamais compresser les images matricielles (JPEG, PNG, WebP) ni les polices woff2 : déjà compressées, le gain est nul et le CPU gaspillé. Pour mesurer ce qui est réellement servi, inspecter les en-têtes de réponse (Content-Encoding, Cache-Control) dans l'onglet réseau du navigateur. La référence complète des directives figure dans la documentation Apache de mod_expires.
Redirections propres : HTTPS et www
Les redirections décident de l'URL canonique du site. Deux règles couvrent l'essentiel : forcer HTTPS et choisir une seule forme de domaine (avec ou sans www). Elles se placent au-dessus de # BEGIN WordPress, pour s'exécuter avant le routage vers index.php.
# À placer AVANT le bloc # BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
# 1. Forcer HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# 2. Forcer le domaine sans www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301]
</IfModule>
Commentaire ligne à ligne : RewriteCond %{HTTPS} off teste si la connexion n'est pas chiffrée ; la règle suivante renvoie un code 301 (redirection permanente) vers la même URL en https://. Le second bloc capture le www. en tête d'hôte — %1 reprend le groupe entre parenthèses de la condition — et redirige vers la version nue. Imposer www au lieu de l'inverse se fait en miroir.
Deux précautions. D'abord, un code 301 est mémorisé durablement par les navigateurs : tester avec un 302 (temporaire) tant que la cible n'est pas certaine, puis repasser en 301. Ensuite, sur l'infrastructure Tomco, le forçage HTTPS peut être activé au niveau du panneau — la règle 1 devient alors redondante. Vérifier avant de cumuler, sous peine de double redirection (deux sauts au lieu d'un).
Pour rediriger une ancienne page précise, mod_alias suffit, plus lisible qu'une RewriteRule :
# Redirection 301 d'une URL retirée vers son remplacement
Redirect 301 /ancienne-page /nouvelle-page

Cohabitation avec LiteSpeed Cache
Le plugin LiteSpeed Cache (LSCache) gère lui-même un bloc dans le .htaccess, délimité par # BEGIN LSCACHE et # END LSCACHE (parfois accompagné de # BEGIN NON_LSCACHE). Il est inséré et régénéré automatiquement à chaque modification des réglages du plugin.
Ne jamais éditer ce bloc à la main. Toute modification est écrasée à la prochaine sauvegarde des réglages LSCache, exactement comme le bloc WordPress. Sur Enhance Panel (Tomco), il est régénéré à chaque activation du plugin — la procédure complète figure dans le tutoriel configurer LiteSpeed Cache sur WordPress.
La cohabitation est simple si l'on respecte un principe : ne pas dupliquer ce que LSCache et le serveur font déjà. Le cache de pages, la conversion WebP à la volée et une partie des en-têtes de cache sont pris en charge par LSCache ; la compression et le cache navigateur le sont par le serveur. Le .htaccess manuel se cantonne alors à ce qui relève vraiment de l'administrateur : les règles de sécurité et les redirections vues plus haut. La documentation LiteSpeed décrit le contenu exact du bloc généré.
Ordre recommandé du fichier, de haut en bas : redirections (HTTPS, www), règles de sécurité (Files, FilesMatch, user-agents), bloc # BEGIN LSCACHE (géré par le plugin), puis bloc # BEGIN WordPress (géré par le cœur). Les deux derniers ne se touchent pas ; les deux premiers sont à vous. Cette répartition vaut pour toute l'architecture LiteSpeed de Tomco, où le .htaccess est lu nativement, sans surcouche ni conversion.
