htaccessのHTTP_HOSTの<If>条件がPHPを壊す

Sep 20 2020

TYPO3セキュリティガイドラインで提案されているように、共有ホスティングウェブスペースがfoo.php.wrongのような偽のファイル名でPHPをレンダリングしないように強化したいと思います。詳細については、https://stackoverflow.com/a/61760273/3946047

Apache構成にアクセスできないため、構成を.htaccessファイルに追加したいと思います。ただし、ローカル開発環境と本番環境の両方.htaccessファイルを機能させるには、本番環境と他のすべての環境を区別するための条件でコードをラップする必要があります。<If>

しかし、条件を追加するとすぐに、すべてのPHPファイルでPHPレンダリングが失敗します。代わりに、ソースコードが表示されます。それが私の巨大な.htaccessファイルの問題ではないことを確認するために、私は空のディレクトリで新しいサブドメインを作成し、これを.htaccessファイルに入れました:

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

これは、条件がコメント化されている限り機能します。条件をアクティブにすると、index.phpのような有効なPHPファイルでさえ、レンダリングされずにソースコードのみが表示されます。

application/x-httpd-php73私のプロバイダーはいくつかのPHPバージョンを提供しているため、特別なタイプが必要です。

したがって、私の問題は構成自体ではなく、状態です。これを修正する方法はありますか?

回答

MrWhite Sep 20 2020 at 07:47
#<If "%{HTTP_HOST} =~ /^(.+)example\.com$/"> RemoveType .php <FilesMatch ".+\.php$">
    AddType application/x-httpd-php73 .php
    SetHandler application/x-httpd-php73
</FilesMatch>
#</If>

これは「失敗」します。これ、PHPハンドラーを再度有効にする内部<FilesMatch>セクション(セクション内<If>)が実際に処理されることがないためです。これは、セクションがマージされる順序と関係があります。

<If>ブロック内のディレクティブを囲むと、処理の順序が変わります。<If>セクションの内容は、(および)セクションがマージされた 、非常に遅くマージされます。したがって、セクションが処理される時点では、子(または)コンテナを処理するには遅すぎるようです(処理されるコンテナはすでに処理されているため)。これは確かに非常に直感に反しており、Apacheのドキュメントには、私が見る限り、これについての「警告」はないようです。<Files><FilesMatch><If><Files><FilesMatch><Files>

これは、簡単な例(すべてのリクエストとすべてのファイルに適用されます)で示すことができます。

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

なしで<If>ラッパー、両方IF_OUTERIF_INNER_FILES環境VARSが設定されています。しかし、<If>ラッパー(後半マージされるブロックを引き起こす)、IF_INNER_FILESのenv VARが設定されていません。mod_setenvif、mod_rewriteなど、どのディレクティブが使用されているかは関係ありません。セクション<Files>内の内部ブロック<If>は処理されません。


ただし、mod_rewriteを使用する別の方法を使用して、フォームの悪意のある要求をブロックすることもできますfoo.php.wrong。例えば:

RewriteEngine on    

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

URLパスに含まれるexample.com(厳密に言えば、で終わるホスト名example.com)へのリクエストは.php.、単に404を返します。

ただし、これを.htaccessファイルの別の部分に配置する必要がある場合があります。できれば上部近く。RewriteEngineディレクティブがすでに存在する場合は、ディレクティブを繰り返す必要はありません。


開発サーバー(または「ライブサーバー」)を識別する方法は他にもあるかもしれません。例えば。あなたは可能性Defineのために開発サーバーの設定とチェック内の変数不在使用して、このの<IfDefine>では.htaccess代わりに。

たとえば、開発サーバーの構成では、次のようになります。

Define DEVELOPMENT_SERVER

次に、.htaccessで、ライブサーバーを識別するためにこれが定義されていないことを確認します。

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