WordPress 2.8.4 がリリースされました。WordPress 2.8.2 → 2.8.3 に続くセキュリティリリースというわけですが、PHP の変数型のフレキシブルさを逆手にとった脆弱性のようです。実際 2.8.3 でやってみると、簡単にパスワードのリセットができてしまいました。

WordPress 2.8.3: パスワードのリセット完了画面

乗っ取られはしないが、イタズラでパスワードがリセットされる

日本語版公式サイトによると、

特別に作成された URL がリクエストされると、ユーザーがリクエストしたパスワードのリセットを確認するためのセキュリティチェックを攻撃者が回避できる可能性があります。その結果、データベースにキーを持たない最初のアカウント (通常は管理者アカウント) のパスワードがリセットされ、新しいパスワードがそのアカウントのメールアドレスに送られます。

ということで、パスワードが乗っ取られるわけではないですが、ピンポンダッシュイタズラにせよパスワードがリセットされるのは時間の無駄なので、サクリとアップグレード推奨と。

自動アップグレードの問題はさすがにもう報告されていないようですが、今回も手動でアップグレードしました。いい加減、自分のブログに書いてあるアップグレード手順を見ないで素でアップグレードできるようになってしまったので、その方が信頼できたりします。

「特別に生成された URL」= 文字列型以外の URL?

今回の脆弱性を書いてある元ネタかどうかは不明ですが、こういうページを発見。

WordPress unauthenticated administrator password reset

パスワードリセットの時に、WordPress は例えば下記のような key のついた URL を生成し、アカウントの所有者にメールが送られます。

http://www.example.com/wp-login.php?action=rp&key=abcdefgh

(abcde… の部分はランダムなキーが入る)

公式サイトではさすがに「特別に作成された URL」 (a specially crafted URL) とボカしてありますが、どうも上記サイトの例だと、悪意のあるユーザが例えば

http://www.example.com?variable[]=value1&variable[]=value2

のように変数名のところを配列変数に変えた URL を送りつけてきても、WordPress 2.8.3 までには変数の型までチェックしていないため、key の正当性をチェックしている部分をすり抜けてしまうと。その結果、「何でも良いけど最初に格納されているキーのないユーザ」=「たいていはアカウント admin」のパスワードがリセットされてしまうという結果になるようです。

上記の通りに書いてもだめですが、一度分かってしまえばなるほど…な「特別に生成された URL」を、自分のテストサイトに送りつけると

WordPress 2.8.3: パスワードのリセット完了画面

他人でも簡単にパスワードのリセットが確かにできてしまいます。

だからといって、パスワードリセット確認用のメールは、登録されたメールアドレスに送られるため、送り先のメールボックスをクラックするという合わせ技でも使わない限り、この脆弱性単独で WordPress を乗っ取ることはできませんが。

変数の型を明示的に宣言しないで使えるのが、PHP という言語のお気楽極楽なところですが、探せばこの手の型チェックが不十分な箇所を突いたセキュリティホールは他にもありそうで恐いですね…。

具体的に WordPress 2.8.4 でどう強化されたかは次回。

つづく。