RewriteCond Apache - Maîtrisez vos règles .htaccess

Xavier Moreau .

11 mai 2026

Extrait de fichier .htaccess montrant des directives `RewriteCond` pour la réécriture d'URL WordPress.

La directive RewriteCond sert à poser des conditions avant qu’Apache applique une règle de réécriture dans un fichier .htaccess. C’est l’outil qui permet de décider quand forcer HTTPS, quand laisser passer un fichier statique, quand normaliser un domaine ou quand bloquer une requête trop suspecte. Ici, je vais aller droit au but: comprendre la logique, choisir les bonnes variables, écrire des règles propres et éviter les pièges qui font perdre du temps en production.

Ce qu’il faut retenir avant d’écrire une condition de réécriture

  • RewriteCond ne réécrit rien seule: elle filtre la RewriteRule qui suit.
  • Plusieurs conditions se cumulent par défaut en AND; le flag [OR] change ce comportement localement.
  • En .htaccess, on travaille en contexte par répertoire, donc la lecture du chemin n’est pas toujours celle qu’on imagine.
  • Les variables les plus utiles sont souvent %{HTTPS}, %{HTTP_HOST}, %{REQUEST_FILENAME}, %{QUERY_STRING} et %{HTTP_USER_AGENT}.
  • Les règles les plus robustes sont simples, explicites et testées une par une avant le passage en 301.

À quoi sert RewriteCond dans un .htaccess

Je lis RewriteCond comme un garde-fou. La directive définit une condition qui doit être vraie pour que la règle suivante s’exécute, et c’est précisément ce qui rend mod_rewrite utile dans des scénarios DevOps très concrets: contrôle du protocole, canonicalisation d’URL, routage vers un front controller, blocage de certains profils de requêtes. Sans elle, on finit vite avec des règles trop larges, donc fragiles.

La forme générale est simple: une variable à tester, un motif à comparer, puis éventuellement des flags. En pratique, dans un fichier .htaccess, je l’utilise surtout pour encadrer une RewriteRule au lieu de multiplier les exceptions dans l’application elle-même. C’est propre tant que la logique reste de l’ordre du routage ou de la sécurité de surface; dès que la décision dépend du métier, je préfère la couche applicative.

Le point à garder en tête, c’est qu’une condition n’agit jamais seule. Elle sert à dire: « applique la règle seulement si tel état du serveur, de l’hôte, du chemin ou de la requête correspond à ce que j’attends ». C’est ce changement de perspective qui évite le bricolage. Une fois cette logique posée, le vrai sujet devient l’enchaînement des conditions et la portée de chaque variable.

Comment la logique conditionnelle s’enchaîne avec RewriteRule

Le comportement par défaut est plus strict qu’il n’y paraît: plusieurs RewriteCond sont évaluées comme un AND. Si l’une échoue, la règle associée ne passe pas. C’est utile pour écrire des filtres précis, mais c’est aussi la source de beaucoup d’erreurs, parce qu’on oublie qu’une seule condition mal pensée suffit à bloquer tout le bloc.

Voici le schéma mental que j’utilise: la règle est la sortie, les conditions sont les verrous. Les tests sont lus dans l’ordre, et le flag [OR] permet de former une alternative locale entre deux conditions. En dehors de ce cas, il n’y a pas de logique magique: Apache ne devine pas l’intention, il exécute exactement ce qui est écrit.

RewriteCond %{REMOTE_ADDR} ^10\.2\. [OR]
RewriteCond %{REMOTE_ADDR} ^192\.168\.
RewriteRule ^ - [F,L]

Dans cet exemple, je bloque deux plages d’adresses privées sans dupliquer la règle. Le flag [F] renvoie un refus, et [L] arrête le traitement du bloc. Ce type d’écriture est lisible parce qu’il sépare bien la condition d’accès et l’action à prendre.

Il y a aussi une distinction qu’on confond souvent: les groupes capturés dans RewriteRule s’utilisent avec $1, $2, etc., tandis que ceux capturés dans RewriteCond se récupèrent avec %1, %2. Cette différence paraît minuscule, mais elle évite des heures de débogage quand on commence à réécrire des URLs de façon plus avancée. À partir de là, le vrai enjeu devient le choix des bons tests.

Les variables et tests qui reviennent le plus souvent

Quand je travaille sur une configuration Apache, je reviens presque toujours aux mêmes variables. Elles couvrent 80 % des besoins courants sans forcer des expressions inutiles ou des vérifications coûteuses. Le tableau ci-dessous résume les cas les plus utiles en contexte .htaccess.

Test ou variable Ce que ça vérifie Usage typique Point d’attention
%{HTTPS} Si la requête est passée en HTTPS Forcer le chiffrement À adapter si un proxy termine TLS en amont
%{HTTP_HOST} Le nom d’hôte demandé Passer de www à non-www ou l’inverse Attention aux sous-domaines et aux boucles de redirection
%{REQUEST_FILENAME} avec !-f et !-d Si le chemin cible existe déjà comme fichier ou dossier Laisser passer les assets avant le routeur frontal Très utile en contexte répertoire, moins intuitif au début
%{QUERY_STRING} Les paramètres de la requête Détecter un paramètre, filtrer une campagne, protéger un endpoint Ne jamais reconstruire une redirection à partir d’une entrée brute
%{HTTP_USER_AGENT} La chaîne User-Agent du client Filtrage simple de bots ou adaptation légère du contenu Ce n’est pas une barrière de sécurité fiable
expr Une expression Apache plus riche qu’un simple motif Logique conditionnelle plus lisible Intéressant quand les regex deviennent trop opaques

Deux flags valent aussi le détour. [NC] rend la comparaison insensible à la casse, ce qui est utile sur des hôtes ou des user-agents, mais sans effet sur les tests système comme -f ou -d. [NV] est plus pointu: il évite d’ajouter un en-tête au Vary, mais je le garde pour les cas où je maîtrise vraiment les effets sur le cache. Les tests qui déclenchent des sous-requêtes, comme -F ou -U, méritent encore plus de prudence, car ils peuvent coûter cher en performance.

Quand ces variables sont bien choisies, les règles deviennent beaucoup plus lisibles. C’est exactement ce qu’il faut pour écrire des cas concrets sans transformer le fichier en labyrinthe.

Des exemples concrets à réutiliser

Dans les projets réels, je finis presque toujours par retomber sur trois scénarios: forcer le protocole, stabiliser le domaine canonique et laisser passer les ressources existantes avant le routeur applicatif. Ces cas sont simples à lire, mais ils couvrent une grande partie des usages sérieux de RewriteCond en production.

Forcer HTTPS proprement

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Cette règle redirige tout trafic non chiffré vers la version HTTPS en conservant le chemin et la chaîne de requête. Je la trouve efficace parce qu’elle reste courte et qu’elle ne mélange pas le contrôle de transport avec d’autres décisions. Si un proxy inverse termine le TLS en amont, je ne réutilise pas cette version brute sans vérifier ce que l’infrastructure transmet réellement à Apache.

Choisir une version canonique du domaine

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]

Ici, le groupe capturé dans la condition alimente la cible avec %1. C’est un bon exemple de la différence entre les captures de condition et celles de règle. Ce genre de redirection me sert à éliminer les variantes inutiles du même site et à éviter que les moteurs ou les caches traitent plusieurs hôtes comme des pages distinctes.

Laisser passer les fichiers avant le routeur frontal

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]

C’est probablement l’usage le plus répandu dans les applications PHP modernes. Si le fichier ou le dossier existe déjà, Apache le sert directement; sinon, la requête arrive sur index.php, qui prend en charge le routage applicatif. Ce pattern évite d’écrire une règle spécifique pour chaque route et garde les assets statiques parfaitement accessibles.

Lire aussi : Apache FQDN - Corrigez l'erreur ServerName et FQDN système

Bloquer un trafic parasite sans toucher au cœur de l’application

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (SemrushBot|AhrefsBot|DotBot) [NC]
RewriteRule ^ - [F,L]

Je n’utilise ce type de filtrage que pour réduire du bruit, jamais comme défense principale. Le User-Agent se falsifie trop facilement pour servir de contrôle d’accès robuste. En revanche, pour calmer des crawlers trop agressifs ou isoler un trafic inutile, c’est parfois suffisant et très rapide à mettre en place. Dès qu’on dépasse ce niveau de complexité, il vaut mieux passer à un filtrage plus sérieux côté pare-feu, reverse proxy ou application.

Ces exemples fonctionnent bien parce qu’ils sont courts, ciblés et faciles à relire. Dès que la règle commence à empiler trop de branches, c’est généralement le signe qu’il faut simplifier ou changer de couche de configuration.

Les erreurs qui font perdre du temps

La première erreur, c’est d’oublier RewriteEngine On. Sans lui, le bloc ne s’exécute pas et on croit à tort que la condition est fausse. La deuxième, c’est d’écrire une condition qui vise le mauvais niveau: en .htaccess, le contexte est per-directory, donc le chemin vu par la règle n’est pas toujours celui qu’on imagine depuis la racine du site.

La confusion entre $1 et %1 revient aussi très souvent. Une autre source de bugs, plus sournoise, consiste à tester le mauvais champ: pour savoir si une ressource existe vraiment, je préfère généralement %{REQUEST_FILENAME} avec !-f et !-d plutôt qu’un motif approximatif sur l’URL. Le résultat est plus fiable et plus lisible pour l’équipe qui reprendra la configuration plus tard.

Je fais également attention aux redirections ouvertes. Si je construis une URL de destination à partir d’une entrée utilisateur non validée, je peux créer une faille de type open redirect sans m’en rendre compte. La bonne habitude consiste à borner les valeurs acceptées et à ne jamais laisser un paramètre brut devenir une cible de redirection absolue. C’est une règle simple, mais elle évite des problèmes réels de sécurité et de réputation.

Enfin, il faut accepter la limite structurelle de mod_rewrite: il travaille sur le chemin d’URL et les en-têtes HTTP, pas sur le corps de la requête. Si la logique dépend d’un payload POST, d’un état métier ou d’un score d’authentification, la bonne place n’est plus le fichier .htaccess. À partir de là, je passe à l’application ou à un autre composant de l’infrastructure.

Quand une règle refuse de se comporter comme prévu, j’augmente temporairement le niveau de log Apache en mode trace et je lis l’ordre réel d’évaluation. C’est l’un des moyens les plus fiables pour comprendre pourquoi une condition n’a pas matché, et c’est bien plus rentable que de modifier la règle à l’aveugle. Avant de pousser en production, je garde encore quelques réflexes simples.

Ce que je garde en place avant de passer en production

Avant un déploiement, je fais toujours le même tri: je teste les règles dans un environnement de préproduction, je valide les cas limites, puis je n’active la redirection permanente qu’une fois le comportement figé. Une règle de réécriture n’est pas difficile en soi; ce qui coûte cher, c’est une règle presque correcte qui casse le cache, le routage ou un sous-domaine oublié.

  • Je commence par une seule règle, puis j’ajoute les conditions une par une.
  • Je vérifie qu’il n’existe pas de boucle de redirection entre version canonique, HTTPS et sous-domaines.
  • Je garde les règles les plus stables au niveau vhost quand c’est possible, et pas seulement dans .htaccess.
  • Je documente brièvement la raison de chaque condition, surtout lorsqu’elle protège une exception métier ou un comportement legacy.
  • Je surveille les logs après mise en ligne, parce qu’une condition qui passe en test peut se comporter autrement avec du trafic réel.

En pratique, RewriteCond est surtout un outil de discipline: il aide à rendre les réécritures explicites, testables et sûres. Si tu gardes la logique simple, si tu distingues bien les variables de requête et les captures de règles, et si tu traites les redirections comme du code d’infrastructure à part entière, tu obtiens une configuration solide au lieu d’un empilement fragile de cas particuliers.

Questions fréquentes

RewriteCond définit des conditions pour qu'une règle de réécriture (RewriteRule) s'applique. Elle permet de filtrer les requêtes selon divers critères (HTTPS, hôte, chemin, etc.) avant d'exécuter une action comme une redirection ou un blocage.
Par défaut, plusieurs RewriteCond sont évaluées avec un opérateur logique AND. Toutes les conditions doivent être vraies pour que la RewriteRule suivante soit exécutée. Le flag [OR] peut être utilisé pour créer une alternative locale entre deux conditions.
Les variables les plus utiles incluent %{HTTPS} pour le protocole, %{HTTP_HOST} pour le domaine, %{REQUEST_FILENAME} pour vérifier l'existence d'un fichier/dossier, %{QUERY_STRING} pour les paramètres d'URL, et %{HTTP_USER_AGENT} pour le client.
$1, $2, etc., font référence aux groupes capturés par la RewriteRule. %1, %2, etc., font référence aux groupes capturés par la RewriteCond. Cette distinction est cruciale pour éviter les erreurs de débogage.
Assurez-vous que RewriteEngine On est activé. Comprenez le contexte per-directory de .htaccess. Distinguez $1 et %1. Testez les règles en préproduction et surveillez les logs. Évitez les redirections ouvertes basées sur des entrées utilisateur non validées.

Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

htaccess rewritecond rewritecond .htaccess exemples rewritecond forcer https
Autor Xavier Moreau
Xavier Moreau
Je m'appelle Xavier Moreau et je cumule 14 ans d'expérience dans le développement web, avec un accent particulier sur JavaScript, le backend, le NoSQL et la sécurité. Mon intérêt pour ces domaines a émergé dès mes débuts dans la programmation, où j'ai découvert la puissance des technologies web et leur capacité à transformer des idées en réalité. J'aime expliquer des concepts complexes de manière accessible, en aidant les lecteurs à naviguer dans les défis techniques qu'ils rencontrent. Au fil des ans, j'ai développé une expertise solide en vérifiant mes sources, en comparant les informations et en simplifiant des sujets parfois ardus. Je m'efforce toujours de fournir des contenus utiles, précis et à jour, en suivant les tendances du secteur et en organisant mes connaissances de manière claire. Mon objectif est d'accompagner les passionnés et les professionnels du développement web dans leur quête de compréhension et d'innovation.

Commentaires (0)

Ajouter un commentaire