先週の Googleが巨大なMD5逆変換テーブルになってる っつう話は世の人々のGeek魂を揺さぶるものがあったようで、わたくしの自己最高記録を更新する数のブックマークをいただきました。ありがとおございます。
それはそれとして、もっと地道な話として、この話の発端でもあるケンブリッジ大学のblogがクラックされる原因になったセキュリティホールが Secuniaで報告 されてます。Not Critical となっていますが、WordPress 管理人諸氏におかれては頭にとめておかれたい。かいつまんで説明すると…
WordPress データベース内部に格納されているユーザのパスワードhash値を何らかの方法で攻撃者が知ってしまった場合、MD5を破るまでもなく、認証cookie を作れてしまう、ていうものです。
WordPressのcookie には、パスワードをMD5で2回hash化したものが格納されてます。なので、攻撃者がDBの中を覗いてadminのパスワードのhash値を見てしまうと、単純にそれをMD5でhash化してcookieを作れば、それでadminとしてログインできちゃうんです。厳密に言うとBlogのURLをhash化した値もついてるけど、そんなもん調べるまでもない。
もちろん、DBの中身を見られなければ破られることも無いんですが、SQLインジェクションとかで覗かれてしまう可能性が怖い。素の WordPress 2.3.1 単体では今のところSQLインジェクション脆弱性は公表されてませんけど、あやしいplugin入れてたりすると夢が無限に広がるから。StatPress Plus 作るときも一応その辺は考えた。
しかしこれって、言われると確かにもっともなんだが、これを防ぐ方法ってあるのか? パスワードを平文でcookieに入れておけば確かに防げるけど、それはそれで別のセキュリティホールになるだろう。Saltを使ったとしても、SaltをDBに入れておくんだとしたら、SQLインジェクションで一緒に見られる可能性が高い。ログインしたときに時刻と乱数でhash生成してそれをセッション識別子としてサーバ側のDBに入れておく… いやそれもDB見られたらセッションハイジャックだよな。SQLインジェクション食らったらもうどうしようも無いっつう気がするのは気のせいか? SaltをDBでなくconfig.phpの方に入れといて、そっちは見られないことを祈る、ぐらいだろか。
結論: SQLインジェクションにはマジで気をつけましょう。パスワードはDB内で一応暗号化されてるけど、それは侵入を防ぐ役には立ってないのよ。
Postedit:
セッションハイジャックについて補足。Cookieにパスワード情報入れずにPHPのセッション機能使ったとしても、サーバ側のDBに格納されたセッションデータをSQLインジェクションによって攻撃者が見てしまうと、セッション管理用cookieを攻撃者が捏造できてしまうよね、と思った。普通のセッションハイジャックと言えばクライアント側のcookie情報が流出するとかだからSSL使えって話になるけど、今回みたいにサーバ側の情報が流出したら手の打ちようがないんじゃないかと。
のだけど、後からよく考えてみると、こんな感じにすればいいのか?
- 乱数をセッションIDとしてcookieに載せて送る。
- サーバ側ではセッションIDをsalt付きでhashした値をセッションデータとして保存する。セッションID自体は保存しない。
- ユーザが次のページを見にきたら、さっき送ったセッションIDがcookieに載って返ってくるはずなので、salt付きでhashしてセッションデータと比較する
これならサーバのDB覗かれてもセッションIDがバレないから大丈夫かな。もちろんクライアント側でcookie情報が流出したら当然ダメだけど。

