PHP $_SERVER["PHP_SELF"]
現在実行中のスクリプト名を取得する$_SERVER["PHP_SELF"]だが、意外な結果を返すケースがある。
以下のファイルをサーバー上に置いて、
test.php
<?php echo '$_SERVER["PHP_SELF"]:'.$_SERVER["PHP_SELF"]."<br>"; echo '$_SERVER["SCRIPT_NAME"]:'.$_SERVER["SCRIPT_NAME"]."<br>"; echo '__FILE__:'.__FILE__; ?>
http://localhost/test.php へアクセスすると、
$_SERVER["PHP_SELF"]:/test.php $_SERVER["SCRIPT_NAME"]:/test.php __FILE__:/var/www/html/test.php
これは想定通りの結果。
だがURLをhttp://localhost/test.php/fooにしてアクセスすると、
$_SERVER["PHP_SELF"]:/test.php/foo
$_SERVER["SCRIPT_NAME"]:/test.php
__FILE__:/var/www/html/test.php
となってしまい、$_SERVER["PHP_SELF"]はファイル名ではなく、Request URLのパスの部分になってしまう(よく見るとリファレンスにも書いてあるのだが)。実行中のスクリプト名を取る場合は、$_SERVER["SCRIPT_NAME"]の方がいいようだ。
先日のZenCartの脆弱性も上記のようなURLでアクセスされることで、$_SERVER["PHP_SELF"]によるリクエスト先の判定を誤り、認証をすり抜けてしまってファイルのアップロードを許してしまっていた。
自分への注意を含めメモ。