Apacheは、Fフラグを無視して、403ではなく404で応答します

Jul 06 2020

私はこの単純なプロジェクト階層を持っています:

ルートフォルダに.htaccessあるファイルの内容/wwwは次のとおりです。

RewriteEngine On

RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} "\.php$"
RewriteRule .* - [F]

のルールは、.phpファイル以外の.phpファイルを要求するときに403.htaccessを返す必要があります。.phpテンプレートの内容は関係ありません。index.php

私が間違っていない場合、リクエストの最後の部分が既存の.phpファイルの名前であり、書き換えエンジンがオンになっていると、.php部分を指定するかどうかに関係なく、Apacheがそれを提供します。私の場合、の最後の2行をコメントアウトすると、.htaccess次のURLのいずれかが表示されます。

localhost/pages/page 
localhost/pages/page/

の内容を返す /pages/page.php

私の問題は、上記のことを考えると、.htaccessこのURLを書くと:

localhost/pages/page.php

期待通り403が出ました。しかし、私が次のいずれかを書いた場合:

localhost/pages/page
localhost/pages/page/

期待される403の代わりに404(見つかりません)を取得します。なぜ404を取得するのですか?

回答

2 MrWhite Jul 06 2020 at 23:33

興味深い... Apache 2.4でこの動作を再現できますが、説明できません。に置き換えるFR=403目的の結果が得られるため、私の意見ではバグのように見えます(違いはないはずです)。以下を参照してください。

明確/pages/pageにするため/pages/page.phpに、最初に解決するためには、有効MultiViewsされているかどうかに依存します(コメントですでに述べられているように)。または、mod_rewriteを使用してこれを行うことができますが、ここではその証拠はありません。マルチビューはApacheではデフォルトで無効になっていますが、一部の共有ホストでは何らかの理由で有効になっています(拡張子のないURLが「正常に機能」するようになります)。ただし、MultiViewsは、mod_rewriteとの予期しない競合の一般的な原因です。また、拡張子のないURLが「(予期せずに)機能する」という事実は、正規化に関して追加の問題を引き起こす可能性があります。

「バグ」があると思う理由は、Fフラグをに変更するだけでR=403、「予期される」403応答が返されるためです。

RewriteCond %{REQUEST_FILENAME} "\.php$"
RewriteRule .* - [R=403]

違いはありませんFR=403。AFAIKは、F単なるショートカットです。


試しましたOptions -MultiViewsが、同じ結果が得られます

ただし、MultiViewsが無効になっている場合は、404期待される応答です。

あなたが要求した場合のMultiViewsは、その後無効にして/pages/pageREQUEST_FILENAMEフォームのものであろう/abs/path/to/pages/page(なし.php拡張子)。条件が一致しないため、リクエストは404にフォールスルーします。

MultiViewを無効にして作業することをお勧めします。これは、「通常」のためではない/pages/page/pages/page/し、「魔法」と決意/pages/page.php。のは、「ノーマル」である/pages/page/pages/page/、このシナリオでは404になります。要求されたURLがファイルシステムにマップされるmod_rewriteで多くのことをしている場合、競合が発生する可能性があります。

MultiViewsは.phpファイルだけに適用されるわけではないことに注意してください。MultiViewsを有効にすると、拡張機能のないすべてのものが得られます。画像、スクリプト、HTML、スタイルシートなど。共通のベース名とmimeタイプを持つ複数のファイルがある場合、どれが提供されますか?例えば。foo.phpまたはfoo.html

もちろん、mod_rewriteディレクティブを作成してこの動作を有効にすることはできますが、これは自動ではありません。


更新:より簡潔な例...

/page.php(ドキュメントルート内の)ファイルがあり、MultiViewsが有効になっている場合
(例Options +MultiViews

リクエスト/page(または/page/)すると/page.php、内部サブリクエストよりも経由でMultiViews / mod_negotiationが提供されます。

ここで、mod_rewriteを使用してすべてのアクセスをブロック、403Forbiddenを提供しましょう。

RewriteRule ^ - [F]

これはブロックする必要があり、すべての要求、しかし403で要求を/page/page/-されたURLに成功代わりに404が見つかりませんでした応答の結果-のMultiViewsによって書き換えられました!

ただし、R代わりにフラグを使用するように上記のルールを変更してください。

RewriteRule ^ - [R=403]

これで、上記の2つのURLを含め、すべてが403を返します。しかし、FR=403同じ動作になるはずです。