<If> condição com HTTP_HOST em htaccess quebra o PHP
Eu gostaria de fortalecer meu espaço da web de hospedagem compartilhada para evitar que ele renderize PHP com nomes de arquivo falsos como foo.php.wrong, conforme sugerido nas Diretrizes de Segurança TYPO3 . Para detalhes veja tambémhttps://stackoverflow.com/a/61760273/3946047
Como não tenho acesso à configuração do Apache, gostaria de adicionar a configuração ao meu .htaccessarquivo. Mas para fazer o .htaccesstrabalho de arquivo em ambos , meu ambiente de desenvolvimento local e na produção, eu preciso para quebrar o código com uma <If>condição de distinguir entre produção e todos os outros ambientes.
Mas assim que adiciono a condição, a renderização do PHP falha para todos os arquivos PHP. Em vez disso, o código-fonte é mostrado. Para verificar se não é um problema do meu .htaccessarquivo enorme , criei um novo subdomínio com um diretório vazio e coloquei no .htaccessarquivo:
<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>
Isso funciona desde que a condição seja comentada. Quando eu ativo a condição, mesmo os arquivos PHP válidos como index.php mostram apenas o código-fonte em vez de serem renderizados.
O tipo especial application/x-httpd-php73é necessário porque meu provedor oferece várias versões de PHP.
Portanto, meu problema não é a configuração em si, mas a condição. Alguma ideia de como posso consertar isso?
Respostas
#<If "%{HTTP_HOST} =~ /^(.+)example\.com$/"> RemoveType .php <FilesMatch ".+\.php$"> AddType application/x-httpd-php73 .php SetHandler application/x-httpd-php73 </FilesMatch> #</If>
Isso "falha" porque a <FilesMatch>seção interna (dentro da <If>seção), que reativa o manipulador de PHP nunca é realmente processada. Isso tem a ver com a ordem em que as seções são mescladas .
Circundar as diretivas em um <If>bloco muda a ordem de processamento. O conteúdo da <If>seção é mesclado muito tarde, depois que as seções <Files>(e <FilesMatch>) são mescladas. Portanto, parece que no momento em que a <If>seção é processada, é tarde demais para qualquer recipiente filho <Files>(ou <FilesMatch>) ser processado (uma vez que todos os <Files>recipientes - que devem ser processados - já foram processados). Embora isso seja reconhecidamente muito contra-intuitivo, e não pareça haver nenhum "aviso" disso, pelo que posso ver, nos documentos do Apache.
Isso pode ser demonstrado com um exemplo simples (que se aplica a todas as solicitações e todos os arquivos):
<If true>
SetEnv IF_OUTER 1
<Files *>
SetEnv IF_INNER_FILES 1
</Files>
</If>
Sem o <If>wrapper, as variáveis de ambiente IF_OUTERe IF_INNER_FILESsão definidas. No entanto, com o <If>wrapper (fazendo com que o bloco seja mesclado tardiamente), o IF_INNER_FILESenv var não é definido. Não importa quais diretivas são usadas: mod_setenvif, mod_rewrite, etc. o <Files>bloco interno dentro da <If>seção nunca é processado.
No entanto, você pode usar um método alternativo usando mod_rewrite para bloquear solicitações maliciosas do formulário foo.php.wrong. Por exemplo:
RewriteEngine on
RewriteCond %{HTTP_HOST} example\.com$
RewriteRule \.php\. - [R=404]
Qualquer solicitação para example.com(estritamente falando qualquer nome de host que termine com example.com) que contenha .php.no caminho do URL retornará simplesmente um 404.
No entanto, pode ser necessário colocá-lo em uma parte diferente do .htaccessarquivo. De preferência perto do topo. Você não precisa repetir a RewriteEnginediretiva se ela já estiver presente.
Também pode haver outras maneiras de identificar seu servidor de desenvolvimento (ou melhor, o "servidor ativo"). por exemplo. Você poderia Defineuma variável na configuração do seu servidor de desenvolvimento e verificar a ausência dela usando <IfDefine>em .htaccessvez disso.
Por exemplo, na configuração do seu servidor de desenvolvimento:
Define DEVELOPMENT_SERVER
Em seguida .htaccess, verifique se isso não está definido para identificar o servidor ativo:
<IfDefine !DEVELOPMENT_SERVER>
# Processed only on live server...
</IfDefine>