なぜPHPアプリにセキュリティホールが多いのか?
第1回 CVEでみるPHPアプリケーションセキュリティ
PHPアプリケーションの脆弱性は本当に多いのか?
アプリケーションの脆弱性を調べるには,CVEを参照するのが簡単です。
CVEとは,NISTが公開しているソフトウェアの脆弱性データベースです。脆弱性を一意に特定できるIDを付与することを目的としています。Webアプリケーションの脆弱性もCVEに登録されています。CVEに2006/12/31に登録されたアプリケーションの脆弱性の数(同じアプリケーションは除く)は次の通りでした。日によって登録される脆弱性の数は異なります。12月31日は比較的多くの脆弱性が登録されました。

通常どおりPHPアプリケーションの脆弱性が目立ちます。特にこの日は同じアプリケーションで複数の脆弱性が登録されていたものがいくつかありました。
同じアプリケーションだけでなく,同じカテゴリの複数のアプリケーションに同じような脆弱性が見つかっている例もあります。
例えば「The Address Book」には8つのエントリが作成されています。多くのPHPアプリケーションの脆弱性が報告されているため,PHPアプリケーションの脆弱性が非常に目立つ形になっています。
PHPアプリケーションでの特徴的な脆弱性
これらのPHPアプリケーションの脆弱性の中でも注目すべき脆弱性があります。「リモートファイルインクルード脆弱性」は多数のエントリが昨年後半くらいから登録されるようになった脆弱性です。

「リモートファイルインクルード脆弱性」はinclude/require文でユーザ入力を未検証のまま使用すると発生する脆弱性です。
require($_GET['base_dir'].'/file_to_include.php');
等のコードがあると,$_GET['base_dir']に「http://example.com/evil.php%00」等を設定することで任意のリモートスクリプトを実行できます。Webサーバ上で任意のスクリプトが実行できてしまうため,サーバの乗っ取りが可能となります。
この脆弱性だけで,例えば以下のようなことが実行可能です。
- データの漏洩(SQLデータデータベースのデータをすべて盗まれる,ファイルを盗まれれる等)
- データの改ざん(不正アカウントの作成,ページの改ざん等)
- 不正サーバの実行(HTTPプロキシ,IRCプロキシ等)
- ほかのサイトへの攻撃
「リモートファイルインクルード脆弱性」が攻撃可能な場合,ありとあらゆる問題が発生する非常に深刻なセキュリティ上の問題です。
register_globalsの罠
12月31日にも8件のリモートファイルインクルード脆弱性が登録されていますが,これらはすべてPHPの設定でregister_globalsが有効に設定されていないと攻撃できない脆弱性です。register_globalsは危険な設定であるため,PHP4.2から互換性を犠牲にしてもデフォルトで無効な状態になるように変更されました。PHP6ではregister_globals設定自体がなくなります。にも関わらずregister_globals=onの状態でしか攻撃できない問題が登録され,PHPアプリケーションの脆弱性の数をかさ上げしている形になっています。
これは,ホスティング会社やサーバ管理者によっては,register_globals=onではセキュリティ上の問題があるにも関わらず,互換性のためにregister_globals=onに設定しているWebサーバが比較的多くあるからです。PHPで作られた有名なECアプリのOSCommerceはregister_globals=onが必要なアプリケーションの代表例です。
OSCommerce自体はregsiter_globals=onでも問題なく動作するように作られているのですが,最近作られたPHPアプリケーションはregister_globalsは無効であることを前提に作成されています。このため,register_globalsが有効なサーバでこれらのアプリケーションを実行すると問題が発生する場合があります。
例えばアプリケーション中に
require($base_dir.'/file_to_include.php');
のようなコードがあると
require($_GET['base_dir'].'/file_to_include.php');
と記述しているのと同じなってしまう場合があります。
対策
このような脆弱性の場合,これはPHPアプリケーションの脆弱性なのかサーバ設定の脆弱性なのか異論のある問題といえます。
PHPアプリケーションを公開する場合,regsiter_globals=offを前提にコーディングしたコードを公開しても構わないですが,必ず以下のようなコードが最初に実行されるようにしてから公開したほうがよいでしょう。不本意にCVEに登録されてしまうことを防ぐことができます。
if (ini_get('resiger_globals')) {
trigger_error('このアプリケーションはregister_globals=onでは動作しません', E_UESR_ERROR);
exit; // 確実に実行を終了する
}
なぜPHPアプリにセキュリティホールが多いのか?
-
Webアプリセキュリティ対策入門〜あなたのサイトは大丈夫?
本書は,Webサイトのセキュリティ確保のために必要な基礎知識と,安全なコードを書くために必要な基礎知識を解説しています。Webアプリケーションは比較的簡単に作成で...
-
はじめてのPHP言語プログラミング入門
Webアプリケーション構築ツールとしてPHPを取り上げた書籍は数多くありますが,言語の解説・入門書としての書籍はあまりありません。 本書は,プログラミング言語として...


