PHP4.2.xではmb_eregは複数行モードで動作していた大垣さんのブログエントリに刺激を得て、古いmb_eregの挙動を調査しました。PHP4.2.x上のmb_eregは複数行モードで動作していたことが分かりましたので報告します。使うべきであることを説明しました。いう形で全体一致検索を指定したつもりでも、簡単にチェックをすり抜け重大な脆弱性に直結します。PerlやPHPの正規表現はデフォルトでは単一行モードであるので、文字列末尾の改行をチェックできないという問題はあるものの、重大な脆弱性に直結するケースはあまりないと考えられることを指摘しました。古いバージョンのmb_eregはデフォルトが複数行モードだった?ところが昨日大垣さんの書かれたエントリ「なぜRubyと違い、PHPの正規表現で^$の利用は致命的な問題ではないのか?」には以下のように書かれていました。実は古いmbregex(忘れるくらい古い4.xの時代の話です)はRubyと全く同じ動作をしていました。この動作はセキュリティ上の問題であるとして、現在の^は\A(データの先頭)と同じ、$は\Z(改行を含む終端にマッチ)に変更されました。私がPHPに親しむようになったのはPHP5.2以降のことなので、「忘れるくらい古い4.xの時代の話」は知らないのですが、どうしても知りたいと思い調べてみました。PHP4.4.9とPHP5.0.0以降のバイナリはすべてありますが、それより古いPHPはありません。そこで、この機会に、すべてのPHP4もビルドすることを決意いたしました。phpall完全版とでも言いましょうかwphall完全版phpall完全版と言っても、ここからPHPの古いソースをダウンロードしてビルドするだけです。@hnwさんが指摘するように、PHP5の古いバージョンをビルドするのはコツがいります。コンパイルできないという問題点があります。修正する必要があります。こんなときgcc3でコンパイルするのも一つの手ですが、MacOSX10.4や10.5ではgcc3が提供されていません。今後このような環境が増えてくるのではないでしょうか。5.2.0-5.2.3は./configureの途中で下記のように怒られてしまいます。executables.原因は追いかけていませんが、autoconfでconfigureスクリプトを作り直すと問題なくバイナリのビルドまで通ります。5.2.0-5.2.3の問題については、独自の調査により新たな知見を得ております。12.04LTSにて確認)。g++この方法で、私はこれまでに200回2回ほどPHP5.2.0-5.2.3のビルドに成功しています。C++コンパイラが動かないよというメッセージに素直に従っただけということですがwPHP4については、gccのバージョンが上がりチェックが厳しくなったためにエラーになる箇所が複数ありました。具体的には、static変数をextern宣言している等です。これらは、ソースの方を修正しました。先のアーカイブにはPHP3.0.18のソースもあったので、ついでにこれもビルドしました。いうことで、PHP3.0.18、PHP4全て、PHP5全てを含む「phpall完全版」の誕生です。試してみる以下のソースで試してみました。$a));実行結果は下記となります。4.2.0以降なので、該当バージョンのみ示します。4.2.xでは、大垣さんの指摘のように、mb_eregが複数行モードで動いていたようです。4.3.0でこの仕様は単一行モードに変更されていますが、その理由は、大垣さんの言われる「セキュリティ上の問題」というよりは、eregと仕様を合わせたということではないでしょうか。すると、ereg関数の呼び出しがmb_eregにオーバーロードされるわけで、eregとの互換性は重要です。使っていると、前述のような脆弱性となる可能性があります。4.2はとっくの昔のサポートが終了しているので、最新のPHPに移行するようにしましょう。XPが長くサポートされてきたかをあらためて感じました。まとめ大垣さんの指摘に刺激を受けて、古いmb_eregの挙動を調査しました。その結果、PHP4.2.xのmb_eregは複数行モードで動作することを確認しました。用いるようにしましょう。PHP4.xを使っているサイト(まだ結構あります)は早急にPHPの最新版に移行しましょう。