2012年4月5日木曜日

PHP5.4.0でheader関数の脆弱性が修正された

PHPのheader関数にはHTTPヘッダインジェクション脆弱性がありましたが、PHP5.4.0で修正されていることを確認しましたので報告します。

PHPのheader関数はHTTPレスポンスヘッダを送信するための関数です。元々header関数には改行文字のチェックが入っていなかったので、HTTPヘッダインジェクション脆弱性が入りやすかったのですが、PHP4.4.2 および 5.1.2の修正として、「この関数は一度に複数のヘッダを送信できないようになりました。 これは、ヘッダインジェクション攻撃への対策です。」と、改行文字が入っている場合、レスポンスヘッダを送信しないようになりました(header関数のマニュアル参照)。

しかし、このチェックはラインフィード(0x0A)しかチェックしておらず、キャリッジリターン(0x0D)のみを使ったHTTPヘッダインジェクション攻撃が可能な状態でした。この状況は、拙著「体系的に学ぶ 安全なWebアプリケーションの作り方」のP205にコラム「PHPのheader 関数はどこまで改行をチェックするか」として説明しています。

これに対して、PHP5.4.0で、header関数がキャリッジリターンもチェックするように修正されました。
https://bugs.php.net/bug.php?id=60227に改訂履歴があります。廣川類さんが担当してくださったのですね。報告者として私の名前もあります。廣川さんありがとうございました。
手元の環境で確認したところ、PHP5.3.10では変更なし(キャリッジリターンを許容)、PHP5.4.0ではキャリッジリターンを含むヘッダ全体が送信されなくなりました。

私の本では、header関数の呼び出し側で改行文字をチェックすることを推奨していますが、PHP5.4.0以降でその必要はなくなりました。しかし、まだまだPHP5.3を使うケースも多いと思うので、当面の間は、header関数の呼び出し側で改行文字をチェックした方がよいでしょう。

ところで、header関数は、どうやってアプリケーションにエラーを返すのでしょうか。マニュアルを見ると、header関数はvoid型で、返り値は「値を返しません」とあります。例外も発生しません(PHPの組み込み関数は原則的に例外を発生させません)。
これは酷い仕様だと思うのですが、header関数(およびその他の組み込み関数)で例外を発生させる方法はあります。これについては次のエントリで説明します。

[PR]
パーフェクトPHP+徳丸本セットを抽選で1名に差し上げちゃうキャンペーン」やってます
安全なWebアプリケーションの作り方」電子書籍版販売しています。電子版はこちら

0 件のコメント:

コメントを投稿

フォロワー