apacheconfまたは.htaccessでRequest_URI
に基づいてSetEnvIf
で環境変数でフラグを立てて、Require
でホワイトリスト判定しているのに拒否される。
通常
SetEnvIf Request_URI {ロケーション}
とRequire
でロケーションで判定するシンプルな例
apacheconf
# http://host/path/to/location でリクエスト
# ロケーションにマッチして環境変数をフラグする
SetEnvIf Request_URI /path/to/location allowed_location
# Requireでフラグを判定して許可
Require env allowed_location
MVCフレームワーク下におけるリダイレクト影響
Webフレームワーク+apache環境ではだいたいmod_rewrite
を使った次のコードスニペットが公開されている。
apacheconf
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
# => http://host/index.php?_url=/path/to/location にインターナルリダイレクトする
原因
上記インターナルリダイレクトでconfの再評価が入るとロケーションが一致しなくなる。
# http://host/index.php?_url=/path/to/location でリクエスト
# ロケーションにマッチしないので環境変数をフラグしない
SetEnvIf Request_URI /path/to/location allowed_location
# Requireでフラグを判定して拒否
Require env allowed_location
対策
リダイレクト後のロケーションもフラグメントするのではさすがに不毛だわ
SetEnvIf Request_URI /path/to/location allowed_location
# リダイレクト後のロケーションもフラグメント
SetEnvIf Request_URI /index.php?_url=/path/to/location allowed_location
# Requireでフラグを判定して拒否
Require env allowed_location
結論
mod_rewrite
によるリダイレクトでは、前回評価で定義した環境変数がREDIRECT_
プレフィックス付きでREDIRECT_{環境変数}
のように引き継がれるので、
Require
にREDIRECT_{環境変数}
を追加して、本来のユーザリクエストに基づく評価結果をもって通過させる。
# リダイレクト再入ではマッチしない
SetEnvIf Request_URI /path/to/location allowed_location
# が、RequireでREDIRECT_allowed_locationを評価して許可
Require env allowed_location REDIRECT_allowed_location