PHP 5.3.0 への移行で脆弱な Web アプリケーションが発生する?

PHP6移行で増える脆弱なWebアプリ(yohgaki's blog) を読んで、結構気になったので、調べてみました。調べてみた結果、私には特に問題となるような箇所は見つけられませんでした。調べたことについてメモしておきます。

問題

PHP6移行で増える脆弱なWebアプリ(yohgaki's blog) で、PHP 6 への移行で脆弱な Web アプリケーションが発生すると指摘されています。その理由として、以下の2点が挙げられています。

  • mb_check_encodingで全ての入力文字エンコーディングが正しいかチェックしていない
  • PHP6のhtmlentities/htmlspecialcharにはマルチバイト文字チェックコードが削除される
http://blog.ohgaki.net/php6-web

さらに、PHP 5.3 でも問題があると書かれています。

追記:PHP5.3のコードを見てみたら、バックポートすべきではないのにバックポートされてました。つまり、PHP6がリリースされたらと言う問題ではなく、今ある問題になっています。一応、改修を提案するつもりですがどうなるか判りません。

この問題は、おそらく、不正な文字列の入力を受けた場合、出力時に htmlentities()/htmlspecialchars() を使用していても、クロスサイトスクリプティングが発生する可能性があるというものだと思います。
問題となる前提条件としては、以下のようになると思います。

  1. PHP スクリプトで、mb_check_encoding() を使用した入力文字コードをチェックをしていない
  2. サーバが PHP 5.3.0 以降(PHP 5.3.0 以降では、htmlentities()/htmlspecialchars() でマルチバイト文字のチェックを行わない)

調べたこと

以下に調べた結果を書いておきます。

まず、PHPCVS から、以下に該当する修正を探してみました。

  1. PHP 6 から PHP 5.3.0 にバックポートされている htmlentities()/htmlspecialchars() への変更
  2. マルチバイト処理関連

その結果、それらしき修正として、以下の1件が見つかりました。

ログには、以下のように書かれていました。

MFH: Added ENT_IGNORE as a compatibility flag for htmlentities() and
htmlspecialchars() to skip multibyte sequences intead of returning an
empty string (as iconv's //IGNORE). These functions will still never
return an invalid or incomplete multibyte sequence.
Fixes #43896

PHP マニュアルには、まだ記載されていませんが、PHP 5.3.0 では、htmlentities()/htmlspecialchars() では、第2引数(quote_style)に、ENT_IGNORE が指定できるようになったという修正です。
ENT_IGNORE を指定すると、第3引数(charset)で指定した文字コードとして評価した場合に不正なバイト列であったとしても、そのまま出力されるようになります。

第2引数のデフォルトは、ENT_COMPAT であり、ENT_IGNORE ではありません。また、ENT_IGNORE を指定しても、それぞれがシングルバイトとして文字エンティティへの変換は行います。
このため、PHP 5.3.0 では、ENT_IGNORE を指定しない(デフォルト)場合、マルチバイト文字列のチェックは行われます。Shift_JISEUC-JP に対するチェックはかなり緩いような気がしますが、それは以前のバージョンから同じです。

htmlspecialchars()/htmlentities() の第2引数(quote_style)のデフォルト値が ENT_IGNORE になるということではありませんので、特にこの変更が直接セキュリティ問題を引き起こすとは考えられません。
他にもいろいろ探してみたのですが、「htmlentities()/htmlspecialchars() でマルチバイト文字のチェックを行っていたコードが削除される」という問題に直接関係のありそうな修正は見つかりませんでした。

まとめ

以上から、私が調べた範囲では、htmlentities()/htmlspecialchars() の関連で PHP 5.3.0 より前のバージョンで、脆弱でなかった PHP スクリプトPHP 5.3.0 以降にバージョンアップすると脆弱になるような問題は見つかりませんでした。

前提条件の読み違えや、私が気付いていない問題などがあるかもしれませんので、絶対に問題ないとは言い切れません。例えば、mb_check_encoding() 自体に問題があるという話であれば、調べた場所が違うということになります。
上記の問題について、近日中に連載 なぜPHPアプリにセキュリティホールが多いのか?(gihyo.jp) で詳細を書かれるということですので、注視しておきたいと思います。

追記(2009.07.25)

上記は問題ないそうです。追記されていました。
別の部分というのがどこかは気になりますが、PHP 5.3.0 にバージョンアップするだけで問題となることはなさそうです。

追記3: 前に読んだ時は斜め読みだったので、もう一度コードをよく見てみると一応必要そうなチェックは入っています。決めうちしているのは別の部分だったので対丈夫でしょう。

http://blog.ohgaki.net/php6-web