<Si> condition avec HTTP_HOST dans htaccess casse PHP
Je voudrais renforcer mon espace Web d'hébergement partagé pour l'empêcher de rendre PHP avec de faux noms de fichiers tels que foo.php.wrong, comme suggéré dans les directives de sécurité TYPO3 . Pour plus de détails, voir aussihttps://stackoverflow.com/a/61760273/3946047
Comme je n'ai pas accès à la configuration Apache, j'aimerais ajouter la configuration à mon .htaccessfichier. Mais pour que le .htaccessfichier fonctionne à la fois dans mon environnement de développement local et en production, je dois envelopper le code avec une <If>condition pour faire la distinction entre la production et tous les autres environnements.
Mais dès que j'ajoute la condition, le rendu PHP échoue pour tous les fichiers PHP. Au lieu de cela, le code source est affiché. Pour vérifier que ce n'est pas un problème de mon énorme .htaccessfichier, j'ai créé un nouveau sous-domaine avec un répertoire vide et l'ai mis dans le .htaccessfichier:
<IfModule mod_mime.c>
RemoveType .html .htm
<FilesMatch ".+\.html?$"> AddType text/html .html AddType text/html .htm </FilesMatch> RemoveType .svg .svgz <FilesMatch ".+\.svgz?$">
AddType image/svg+xml .svg
AddType image/svg+xml .svgz
</FilesMatch>
#<If "%{HTTP_HOST} =~ /^(.+)example\.com$/"> RemoveType .php <FilesMatch ".+\.php$">
AddType application/x-httpd-php73 .php
SetHandler application/x-httpd-php73
</FilesMatch>
#</If>
</IfModule>
Cela fonctionne tant que la condition est commentée. Lorsque j'active la condition, même les fichiers PHP valides comme index.php affichent uniquement le code source au lieu d'être rendus.
Le type spécial application/x-httpd-php73est nécessaire car mon fournisseur propose plusieurs versions de PHP.
Donc mon problème n'est pas la configuration elle-même mais la condition. Des idées pour résoudre ce problème?
Réponses
#<If "%{HTTP_HOST} =~ /^(.+)example\.com$/"> RemoveType .php <FilesMatch ".+\.php$"> AddType application/x-httpd-php73 .php SetHandler application/x-httpd-php73 </FilesMatch> #</If>
Cela "échoue" car la <FilesMatch>section interne (à l'intérieur de la <If>section), qui réactive le gestionnaire PHP, n'est jamais réellement traitée. Cela a à voir avec l' ordre dans lequel les sections sont fusionnées .
Entourer les directives dans un <If>bloc change l'ordre de traitement. Le contenu de la <If>section est fusionné très tard, après la fusion des sections <Files>(et <FilesMatch>). Ainsi, il semble qu'au moment où la <If>section est traitée, il est trop tard pour que les conteneurs enfants <Files>(ou <FilesMatch>) soient traités (puisque tous les <Files>conteneurs - qui doivent être traités - ont déjà été traités). Bien que cela soit certes très contre-intuitif, et qu'il ne semble pas y avoir d'avertissement à ce sujet, pour autant que je sache, dans la documentation Apache.
Cela peut être démontré avec un exemple simple (qui s'applique à toutes les demandes et à tous les fichiers):
<If true>
SetEnv IF_OUTER 1
<Files *>
SetEnv IF_INNER_FILES 1
</Files>
</If>
Sans le <If>wrapper, les variables d'environnement IF_OUTERet IF_INNER_FILESsont définies. Cependant, avec le <If>wrapper (provoquant la fusion tardive du bloc), la IF_INNER_FILESvariable d'environnement n'est pas définie. Peu importe les directives utilisées: mod_setenvif, mod_rewrite, etc. le <Files>bloc interne de la <If>section n'est jamais traité.
Cependant, vous pouvez utiliser une méthode alternative utilisant mod_rewrite pour bloquer les requêtes malveillantes du formulaire foo.php.wrong. Par example:
RewriteEngine on
RewriteCond %{HTTP_HOST} example\.com$
RewriteRule \.php\. - [R=404]
Toute demande à example.com(à proprement parler tout nom d'hôte qui se termine par example.com) qui contient .php.dans le chemin URL renverra simplement un 404.
Cependant, vous devrez peut-être le placer dans une autre partie de votre .htaccessfichier. De préférence près du sommet. Vous n'avez pas besoin de répéter la RewriteEnginedirective si elle est déjà présente.
Il peut également y avoir d'autres façons d'identifier votre serveur de développement (ou plutôt le «serveur en direct»). par exemple. Vous pouvez utiliser Defineune variable dans la configuration de votre serveur de développement et vérifier son absence en utilisant <IfDefine>à la .htaccessplace.
Par exemple, dans la configuration de votre serveur de développement:
Define DEVELOPMENT_SERVER
Ensuite .htaccess, vérifiez que ce n'est pas défini pour identifier le serveur live:
<IfDefine !DEVELOPMENT_SERVER>
# Processed only on live server...
</IfDefine>