タグ: PHP

Example 1428. A “Best Practice” query

PHPのマニュアルページで「Example 1428. A “Best Practice” query」と題されたSQL文用の文字列エスケープ処理のサンプルコードがあるのですが、

$query = sprintf("INSERT INTO products (`name`, `description`, `user_id`) VALUES ('%s', '%s', %d)",
mysql_real_escape_string($product_name, $link),
mysql_real_escape_string($product_description, $link),
$_POST['user_id']);

mysql_query($query, $link);

この方法はよくないですね… $_POST[‘user_id’]は符号付き32ビット整数だと仮定していて64ビット整数や任意精度整数の場合が考慮されていません。”Best Practice”とするなら整数型と思われるuser_idも文字列として処理し、エスケープしてからmysql_queryに渡すべきだと思います。

tidy_parse_string() オーバーフロー

CVE-2007-3294にtidy_parse_string()オーバーフローが登録されています。

http://nvd.nist.gov/nvd.cfm?cvename=CVE-2007-3294

に脆弱性情報のソースURLが記載されています。

http://www.milw0rm.com/exploits/4080

すぐに応用可能な実証コード付きです。Linuxだと影響が大きすぎると考えたのか、実証コードの作成者がWindows環境が得意なのか、Windows環境のコードになっています。

tidy_parse_string()の第二引数(動作設定用パラメータ)のオーバーフローを利用しているので専用サーバで運用しているユーザにはあまり重要な脆弱性ではありません。(普通のコードならローカルからしか攻撃できない)しかし、PHPの場合、共有ホスティング環境で運用すできでないアプリケーション(たとえばECアプリ)も多く利用されているので「Base score: 7.5 (High) 」とレーティングされても仕方ないところでしょう。

PHPセッションの問題修正

Stefanさんのブログに書いてあったので気がついたのですが

http://cvs.php.net/viewvc.cgi/php-src/ext/session/session.c?r1=1.417.2.8.2.35&r2=1.417.2.8.2.36

に結構面白いコミットがされています。CVS版なので正式リリースになるかは不明です。成り行きはがどうなるかは興味深いです。

MOPBで解説されていたセッションIDにインジェクションができる問題を修正しようとブラックリスティングで対応させようとしたようです。ブラックリスティングより暗号化した方が安全性と互換性を確保するのが簡単なのですがZend社の社員によるコミットだったのですがZend Platformとの互換性も維持できないパッチになっているようです。Stefanさんのブログを見るとかなり皮肉な書き方であることが分かります。このような文面になった背景にはZend社の社員により「PHP開発者に知らせず脆弱性を公開した」とあらぬ言いがかりを付けられためだと思います。

非常に古いPHPの場合、セッションIDには好みの文字列が設定できたのですが最近のPHPは

\r\n\t <>’\”\\

が不正な文字として登録されています。\r\nはヘッダスプリティング、<>'”\はXSSに明らかに利用できるので不正としても仕方ない文字ですが、

()@,;:[]?={}&%

も新たに不正な文字に加えられたました。:はZend Platformでも使っている文字だそうです。
備考: セッションIDに管理用の文字列を付け加えるのは珍しいことではありません。負荷分散や分散されたサーバ間でのデータ共有など様々な用途に管理用の文字列を付け加える場合があります。

暗号化による対処の方がシンプルかつ安全な対策だと思います…

ところで、単純にクッキーだけでセッションIDを使っている場合には問題は発生しません。つまりsession.use_trans_sid=0, session.use_only_cookies=1でPHPを使っていれば現在のPHPを使っていてもここで問題としている不具合には影響されません。

PHPMailerコマンドインジェクション – WordPress, Mantis, WebCalendar, Group-Office, Joomla, etc

個人的には影響ないですがいろいろなアプリケーションで使われているPHPMailerと言うクラスにコマンドインジェクションの脆弱性があったようです。リンク先を見ればescapeshellarg()かescapeshellcmd()でエスケープすべき個所がエスケープされていない事が分かります。

どの位危険か?と言うと簡単にサーバを乗っ取られる(不正なプロセスを実行される等。プロキシ、SPAMメール中継、SSHアカウントクラック、DoS、etc)くらい危険です。対処が必要な方は早く対処すべきです。

以下はfull-disclosureのメールです。

PHPMailer is a widely deployed utility class used in PHP application to
handle emails sent through sendmail, PHP mailto() or SMTP. It is used in PHP applications such as WordPress, Mantis, WebCalendar, Group-Office and Joomla. The last official release happened on July 11, 2005.

If you have configured PHPMailer to use sendmail it has a remote command execution vulnerability due to a lack of input validation. sendmail isqueried through the popen function which is called with a string constructed from non-escaped user input.

http://larholm.com/2007/06/11/phpmailer-0day-remote-execution/

Cheers
Thor Larholm

追記:調査を行っていないので何となくですが、ファイルインクルードバグよりコマンドインジェクションバグの方が悪用される確率が高いような気がしています。脆弱性的にはファイルインクルードバグの方が強力ですが、攻撃用コードを別ホストに配置するのが面倒なのか(?)コマンドインジェクションの方が悪用されているような気がします。
# ファイルインクルードバグには攻撃用コードを
# 直接挿入できる場合もあります。

PHP 5.2.3のchunk_split()は未修整だった…

http://blog.php-security.org/archives/84-PHP-5.2.3-released….html にも書いてあるのですが、PHP 5.2.3ではchunk_split()が直っているハズだったのですが直っていませんでした。

Fixed an integer overflow inside chunk_split() (by Gerhard Wagner, CVE-2007-2872)

直したつもりが整数オーバーフローが発生するコードになっており、ヒープオーバーフローが発生します…

CVSには修正コードがコミットされています。

http://cvs.php.net/viewvc.cgi/php-src/ext/standard/string.c?r1=1.445.2.14.2.60&r2=1.445.2.14.2.61

Fix chunk_split fix – avoid using floats
Fix money_format – don’t give strfmon more arguments then supplied
Fix str[c]spn integer overflow

他のセキュリティFIXもあるのでPHP 5.2.4のリリースは近い(?)かな…

Cのコードを読める方なら気が付くと思いますが、整数オーバーフローによりdestバッファに十分なメモリが割り当てられない問題に対してint型の変数とINT_MAXを比較、符号のチェックをしても意味がないのは明白です。(負の値になった時しかチェックしていないので対策になっていない)

この指摘に対してBogusだとかFUDだとか言われるのは非常に心外だと思います。セキュリティ問題に対して正しい姿勢や理解を持っていない開発者と話をするのはかなりの疲労を伴う作業だ、という事がStefanさんのブログからは分かります… 文面からも最近フラストレーションが溜まっているような気もします。コードをチェックするStefanさんがいるPHPといないPHPでは安全性に大きな違いが発生すると思います。Hardened-PHPやMOPBをサポートするにはPayPalによる寄付もありますが応援メールも有効です。(こういうメールは英語が下手でも問題はないです)

PHP 5.2.3リリース

日本語環境でMySQLを利用している方には、リリースノートに記載されているmysql_set_charset()の追加に重要な意味がある方も多いと思います。

Added mysql_set_charset() to allow runtime altering of connection encoding.

PHP4にはまだ追加されていませんがかなり重要なセキュリティフィックスだと思います。mysql_set_charset()はlibmysqlのmysql_set_character_set()の簡単なラッパー関数です。

http://dev.mysql.com/doc/refman/4.1/en/mysql-real-escape-string.html

“If you need to change the character set of the connection, you should use the mysql_set_character_set() function rather than executing a SET NAMES (or SET CHARACTER SET) statement. mysql_set_character_set() works like SET NAMES but also affects the character set used by mysql_real_escape_string(), which SET NAMES does not”

つまりSET NEMESだと文字エンコーディングを利用したSQLインジェクションに脆弱となる可能性があります。共有型サービスを利用されている場合、SET NAMESを使用している方も多いと思います。

ググってみると2005年11月には日本のMySQLユーザ会MLでは問題が認識されていたようです。

MOBPを訳し終えて

もう何年か前になりますがStefanさんがPHPプロジェクトへの貢献を始めたころ「整数オーバーフローの修正はセキュリティ脆弱性なのでそのことを明記すべき」と指摘した事がありました。信じがたいかもしれませんが「攻撃可能かどうか分からないし脆弱性でなく普通のバグ修正だ」と主張する開発者がいたためPHPのこの手のヒープオーバーフローセキュリティ修正は「fixed crash」とCVSログに書いてあるだけの場合が多く、NEWSファイルにも記載されない事が当たり前になっていました。

もっと読む