php.ini で mbstring.encoding_translation を有効にすると max_input_vars が有効にならない(PHP 5.4.8以前、PHP 5.3.18以前)

少し前の話題ですが、PHP 5.4.9 と PHP 5.3.18 が公開されました。その中で、mbstring の項目に「mbstring.encoding_translation = On になっていると max_input_vars が有効にならない」問題が修正されています。

また、詳細や確認方法は徳丸さんが以下にまとめておられます。

再現条件

この件は再現条件が分かりにくいので、少し調べてみました。その結果、以下のことが分かりました。

  1. PHP 5.3.9 で max_input_vars が導入された(hashdos 脆弱性対策)
  2. PHP 5.3.9 〜 PHP 5.3.10 では、mbstring.encoding_translation を有効にしても max_input_vars は有効になる
  3. PHP 5.3.11 と PHP 5.4.0 でチェック方法が変更された
  4. PHP 5.3.11 から mbstring.encoding_translation を有効にすると、max_input_vars が有効にならない

PHP 5.3.11 での修正は以下にあります。Log Message には「Improved max_input_vars directive to check nested variables」とあり、PHP 5.3.9 の修正ではまだ不十分だったのかもしれません。

以上から、PHP 5.3.8 以前のバージョンを配布していた Linux ディストリビューションなどでは PHP 5.3.9 での修正が取り込まれたため、mbstring.encoding_translation が有効でも問題なかったと考えられます。
このため、本件の影響は PHP 5.3.11 〜 PHP 5.3.18 および、PHP 5.4.0 〜 PHP 5.4.8 になると思います。

PHP 5.3.11 以降で PHP をバージョンアップしない場合の対処方法

PHP 5.3.11 以降は mbstring.encoding_translation が無効であれば hashdos 脆弱性はありません。その場合、mbstring.encoding_translation は以下のような PHP スクリプトで代用可能です。

<?php
mb_language( "Japanese" );
$encoding = mb_internal_encoding();
$encoding = mb_convert_variables( $encoding, "ASCII,UTF-8,SJIS-win,eucJP-win", $_POST, $_GET, $_COOKIE );

上記のスクリプトが、最初に実行されるようにします。mb_convert_variables() の第2引数は、php.ini の mbstring.http_input で設定している値にします。ただし、auto を設定するのはあまりお勧めしません。理由は以下を参照してください。