Connector/JのSQLインジェクション脆弱性
PreparedStatement使ってるのにSQLインジェクションが起きるんですけど?という話題。徳丸浩の日記 - JavaとMySQLの組み合わせでUnicodeのU+00A5を用いたSQLインジェクションの可能性より。
再現したのでバグレポート投げておきました。MySQL Bugs: #41730: SQL Injection when using U+00A5です。すてきなパッチで解決されることを期待したいと思います。
うちの社内でcharacterEncoding使ってるところはないから大丈夫なはず…。と思っていたのですが、ブクマコメントをいただいたとおり、character_set_server=cp932の設定がされたmysqldにcharacterEncodingなしでつないだ場合もインジェクションを起こせますね。sjisもujisもeucjpmsもダメです。というわけで、サーバサイドPreparedStatementを使っているか、あるいは
- クライアントサイドPreparedStatement
- character_set_server=utf8
- characterEncodingなし
の設定で動いているシステムが、最も安らかに年末年始を過ごせるといえそうです。
2008/12/26追記
Sunの松信さんが試作パッチを投稿されたようです。試しに1文字ずつエンコーディング変換をしてみて、変換後が0x5cになる文字については\\にしておくと。
えーと、変換後がUCS-2とかだとマズいかな?
…(実験中)…
試作パッチ以前に、Connector/Jでcharacter_set_server=ucs2のサーバに繋がらないんですけど。Connector/J側でcharacterEncoding=UTF-8などとしておけば繋がりますが、こんな仕様あったかな…。
念のためMySQL Bugs: #41752: Can't connect mysqld which character_set_server=ucs2で報告したところ、Verified as described.ということでバグ認定されました。Connector/Jとcharacter_set_server=ucs2の組み合わせって、世界中で誰も使っていなかったようですね。
というわけでBug #41752のせいで実験ができないのですが、UCS-2やUTF-16では第1バイトが0x5cになる文字があるので、エスケープした後にきちんと判定してあげないといけないと思います。また、だんだんロジックが難しくなってしまいConnector/Jの性能が劣化しないかどうかも気になるところです。
2008/12/27追記
ようやくバグシステムから反応があって、担当の方がアサインされたようです。解析結果を待ちたいと思います。
2009/02/19追記
2ヶ月ぶりに動きがありました。
[19 Feb 8:28] Tonci Grgin Sadao, Yoshinori, we are having internal discussion about this bug and it's not forgotten. Thanks.
大幅な設計変更になると思うので、慎重ですね。頑張ってほしいと思います。
2009/02/24追記
パッチができたようです。新しいエントリに移動します。
2009/07/29追記
この脆弱性はConnector/J 5.1.8で修正されました。関連記事を以下に示します。