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-2UTF-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追記

パッチができたようです。新しいエントリに移動します。