<如果>htaccess 中 HTTP_HOST 的条件破坏了 PHP [英] <If> condition with HTTP_HOST in htaccess breaks PHP

查看:25
本文介绍了<如果>htaccess 中 HTTP_HOST 的条件破坏了 PHP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想强化我的共享托管网络空间,以防止它按照 TYPO3 安全指南.详情另见https://stackoverflow.com/a/61760273/3946047

由于我无权访问 Apache 配置,我想将配置添加到我的 .htaccess 文件中.但是要使 .htaccess 文件在 、我的本地开发环境和生产环境中都能正常工作,我需要用 区分生产环境和所有其他环境的条件.

但是一旦我添加了条件,所有 PHP 文件的 PHP 渲染都会失败.而是显示源代码.为了验证这不是我巨大的 .htaccess 文件的问题,我创建了一个带有空目录的新子域,并将其放入 .htaccess 文件中:

删除类型 .html .htm<FilesMatch ".+\.html?$>添加类型文本/html .html添加类型文本/html .htm</FilesMatch>删除类型 .svg .svgz<FilesMatch ".+\.svgz?$>添加类型图像/svg+xml .svg添加类型图像/svg+xml .svgz</FilesMatch>#<如果 "%{HTTP_HOST} =~/^(.+)example\.com$/>删除类型 .php<FilesMatch ".+\.php$>添加类型应用程序/x-httpd-php73 .phpSetHandler 应用程序/x-httpd-php73</FilesMatch>#</如果></IfModule>

只要条件被注释掉,这就会起作用.当我激活条件时,即使是像 index.php 这样的有效 PHP 文件也只显示源代码而不是被渲染.

需要特殊类型 application/x-httpd-php73 因为我的提供商提供了多个 PHP 版本.

所以我的问题不是配置本身而是条件.有什么想法可以解决这个问题吗?

解决方案

#

这个失败"因为内部 部分(在 部分内),重新启用 PHP 处理程序从未被实际处理过.这与合并部分的顺序有关.

块中的指令括起来会更改处理顺序. 部分的内容很晚才合并,after (和 ) 部分合并.因此,似乎在处理 部分时,对于任何子 (或 ;) 要处理的容器(因为任何 容器 - 要处理的 - 已经被处理).尽管这无疑是非常违反直觉的,并且似乎没有任何警告"据我所知,在 Apache 文档中.

这可以用一个简单的例子来证明(适用于所有请求和所有文件):

<如果为真>设置环境 IF_OUTER 1<文件 *>SetEnv IF_INNER_FILES 1</文件></如果>

没有 包装器,IF_OUTERIF_INNER_FILES 环境变量都会被设置.但是,使用 包装器(导致块合并延迟),IF_INNER_FILES 环境变量未设置.使用什么指令并不重要:mod_setenvif、mod_rewrite 等. 部分中的内部 块永远不会被处理.>


但是,您可以使用 mod_rewrite 的替代方法来阻止 恶意 形式的 foo.php.wrong 请求.例如:

RewriteEngine onRewriteCond %{HTTP_HOST} 示例\.com$重写规则\.php\.- [R=404]

example.com(严格来说,任何以 example.com 结尾的主机名)的任何请求,在 URL 中包含 .php.-path 只会返回 404.

但是,您可能需要将其放在 .htaccess 文件的不同部分.最好靠近顶部.如果 RewriteEngine 指令已经存在,则无需重复该指令.


您可能还可以通过其他方式识别您的开发服务器(或者更确切地说,是实时服务器").例如.您可以在开发服务器配置中Define一个变量,并使用.htaccess<中检查缺失/code> 代替.

例如,在您的开发服务器配置中:

定义 DEVELOPMENT_SERVER

然后在 .htaccess 中,检查它是否定义以识别实时服务器:

# 仅在实时服务器上处理...</IfDefine>

I'd like to harden my shared hosting webspace to prevent it from rendering PHP with faked filenames like foo.php.wrong as suggested in the TYPO3 Security Guidelines. For details see also https://stackoverflow.com/a/61760273/3946047

Since I don't have access to the Apache configuration I'd like to add the configuration to my .htaccess file. But to make the .htaccess file work on both, my local development environment and in production, I need to wrap the code with a <If> condition to distinguish between production and all other environments.

But as soon as I add the condition, PHP rendering fails for all PHP files. Instead, the source code is shown. To verify it's not a problem of my huge .htaccess file, I created a new subdomain with an empty directory and put this into the .htaccess file:

<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>

This works as long as the condition is commented out. When I activate the condition, even valid PHP files like index.php only show the source code instead of being rendered.

The special type application/x-httpd-php73 is needed because my provider offers several PHP versions.

So my problem is not the configuration itself but the condition. Any ideas how I can fix this?

解决方案

#<If "%{HTTP_HOST} =~ /^(.+)example\.com$/">
RemoveType .php
<FilesMatch ".+\.php$">
    AddType application/x-httpd-php73 .php
    SetHandler application/x-httpd-php73
</FilesMatch>
#</If>

This "fails" because the inner <FilesMatch> section (inside the <If> section), that re-enables the PHP handler is never actually processed. This has to do with the order in which sections are merged.

Surrounding the directives in an <If> block changes the order of processing. The contents of the <If> section are merged very late, after <Files> (and <FilesMatch>) sections are merged. So, it seems that at the time the <If> section is processed, it is too late for any child <Files> (or <FilesMatch>) containers to be processed (since any <Files> containers - that are to be processed - have already been processed). Although this is admittedly very counter-intuitive, and there does not appear to be any "warning" of this, as far as I can see, in the Apache docs.

This can be demonstrated with a simple example (which applies to all requests and all files):

<If true>
    SetEnv IF_OUTER 1
    <Files *>
        SetEnv IF_INNER_FILES 1
    </Files>
</If>

Without the <If> wrapper, both the IF_OUTER and IF_INNER_FILES environment vars are set. However, with the <If> wrapper (causing the block to be merged late), the IF_INNER_FILES env var is not set. It doesn't matter what directives are used: mod_setenvif, mod_rewrite, etc. the inner <Files> block within the <If> section is never processed.


However, you could use an alternative method using mod_rewrite to block malicious requests of the form foo.php.wrong. For example:

RewriteEngine on    

RewriteCond %{HTTP_HOST} example\.com$
RewriteRule \.php\. - [R=404]

Any request to example.com (strictly speaking any hostname that ends with example.com) that contains .php. in the URL-path will simply return a 404.

However, you may need to place this in a different part of your .htaccess file. Preferably near the top. You don't need to repeat the RewriteEngine directive if it's already present.


There may also be other ways you can identify your development server (or rather, the "live server"). eg. You could Define a variable in your development server config and check for the absence of this using <IfDefine> in .htaccess instead.

For example, in your development server config:

Define DEVELOPMENT_SERVER

Then in .htaccess, check that this is not defined in order to identity the live server:

<IfDefine !DEVELOPMENT_SERVER>
    # Processed only on live server...
</IfDefine>

这篇关于&lt;如果&gt;htaccess 中 HTTP_HOST 的条件破坏了 PHP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆