残り一年! PHP4からPHP5への移行

第5回 セキュリティ関連の違い

この記事を読むのに必要な時間:およそ 5 分

pg_escape_stringとmysql_real_escape_string

PHP5のデータベースの文字列エスケープ関数には,日本語ユーザにとって重要な変更が追加されています。新しいPHP5のデータベース用の文字列エスケープ関数は,接続パラメータが追加されています。これはデータベースサーバへの接続にどの文字エンコーディングが利用されているか考慮せずに文字列をエスケープすると,データベースサーバ側ではSQLインジェクションであるか判定できないクエリが送信されるためで,データベースサーバ接続パラメータがオプションパラメータとして指定できるようになりました。

string pg_escape_string ( [resource $connection, string $data] )
string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier] )

pg_escape_stringとmysql_real_escape_stringではパラメータの並びが異なりますが,使い方は同じです。$connection, $link_idetifierにそれぞれpg_connect関数,mysql_connect関数で取得したデータベース接続リソースの変数を渡します。PHPマニュアルの記述では分かりづらいですが,pg_escape_string関数も従来通り文字列のみを引数として渡しても従来と同様に動作します。

これらの文字列エスケープ関数は接続引数が省略されるとデフォルト接続の文字エンコーディングを利用してエスケープ処理を行います。つまりWebシステムを独自に運用し,すべてのデータベースの文字エンコーディングが統一されている場合,文字列エスケープ関数に接続パラメータを追加指定しなくても正しくエスケープ処理が行われます。共有サーバを利用している場合やデータベースで複数の文字エンコーディングを利用している場合は接続パラメータを省略すべきではありません。

これらの2つの関数が期待通りに動作するためには,PostgreSQL,MySQL共にそれぞれ,

int pg_set_client_encoding ( resource $connection, string $encoding )
bool mysql_set_charset ( string $charset [, resource $link_identifier] )

を利用しなければなりません。詳しい解説は省略しますが,SQL文を発行して文字エンコーディングを変更してしまうとSQLインジェクションに脆弱になる場合があります。PostgreSQLモジュールにはPHP4.2.0からpg_set_client_encoding関数が実装されていたので,PHP4用のコードでもデータベースの文字エンコーディング設定を変更・設定する場合はpg_set_client_encoding関数が利用されていると思います。

MySQLのmysql_set_charset関数はPHP5.2.0から追加された関数であるため,ほとんどのコードはこの関数の代わりに⁠SET NAMES⁠を利用していると思います。SET NAMESでデータベースの文字エンコーディングを設定しているからといってすべての構成でSQLインジェクション脆弱性が発生したりはしませんが,SET NAMESを使用した文字エンコーディング指定はセキュリティ上行ってはならない操作です。MySQLアプリケーションを移行する場合,SET NAMESで文字エンコーディングを指定している箇所はすべてmysql_set_charset関数を利用するように書き換えるほうがよいです※1⁠。

※1
マニュアルにはMySQL 5.0.7以上に付属するlibmysqlが必要と記載されていますが,PHP5のソースコードを読むと4.x系のlibmysqlでもmysql_set_charset関数が利用可能になるコードになっています。mysql_set_charset関数が利用可能なPHPであれば問題ありません。
PHP4のMySQLユーザはどうすべきか?

PHP4にはクライアントAPIを利用した文字エンコーディング設定関数が用意されていません。SET NAMESでデータベース接続の文字エンコーディング設定を行わなくてもよいようデフォルトの文字エンコーディングを設定する回避策があります。

まとめ

現時点ではPHP4は通常メンテナンス(セキュリティフィックスおよびバグフィックスも含む修正あり)状態ですが,PHP5と比べて十分にメンテナンスされているとはいえません。この連載でもPHP4の参照カウンタが簡単にオーバーフローしてしまう不具合を紹介しました。この問題を利用した攻撃方法も知られていますが修正されていません。

とにかくPHP4のメンテナンス終了は2007年12月31日,セキュリティフィックスの提供終了は2008年8月8日です。PHP5への移行の猶予期間は1年を切りました。時間はあまり残されていません。

参考文献
英語版PHPマニュアル - 最新情報の入手には英語版が適しています。
URLhttp://jp.php.net/manual/en/
PHP4からPHP5への移行
URLhttp://jp.php.net/manual/en/migration5.php
PHP5.0からPHP5.1への移行 - PHP4ユーザにも有用な情報が掲載されています
URLhttp://jp.php.net/manual/en/migration5.php
PHP5.1からPHP5.2への移行 - PHP4ユーザにも有用な情報が掲載されています
URLhttp://jp.php.net/manual/en/migration52.php
PHP5の変更履歴
URLhttp://jp.php.net/ChangeLog-5.php
PHP4の変更履歴
URLhttp://jp.php.net/ChangeLog-4.php

著者プロフィール

大垣靖男(おおがきやすお)

University of Denver卒。同校にてコンピュータサイエンスとビジネスを学ぶ。株式会社シーエーシーを経て,エレクトロニック・サービス・イニシアチブ有限会社を設立。
オープンソース製品は比較的古くから利用し,Linuxは0.9xのころから利用している。オープンソースシステム開発への参加はエレクトロニック・サービス・イニシアチブ設立後から。PHPプロジェクトでは,PostgreSQLモジュールのメンテナンスを担当している。

URLhttp://blog.ohgaki.net/

著書