htaccessのHTTP_HOSTの<If>条件がPHPを壊す
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バージョンを提供しているため、特別なタイプが必要です。
したがって、私の問題は構成自体ではなく、状態です。これを修正する方法はありますか?
回答
#<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_OUTER
とIF_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>