UnicodeのU+00A5問題
JavaとMySQLの組み合わせでUnicodeのU+00A5を用いたSQLインジェクションの可能性
なるほど。この問題は初耳だったので驚いた。
しかも、PreparedStatementを使っても解決されないという。この部分に非常に驚いたのでどういうことなのか少し調べてみた。
PreparedStatementとは?
mysqlにおける話としてはPrepared Statement (訳)がとてもわかりやすい。
なかでも重要なのは以下の部分だ。
PerlとJava のユーザはかなり長い間prepared statementを使って きました。しかし、これらはクライアント側のprepared statementでした。 クライアント側のprepared statementは同じようなセキュリティの恩恵 をもたらしますが、性能向上には至りません。でも心配いりません。 MySQL Connector/J は3.1のリリースでサーバーサイドprepared statement をサポートします。
そして実は現在のConnector/Jの最新版(5.1.7)ではデフォルトでは「サーバーサイドprepared statement」を使っていないのである。そしてクライアントサイドのprepared statementは結局のところエスケープ関連のセキュリティ脆弱性を潜在的に抱えてしまう存在なのである。そして実際に今回の問題があった。
Connector/JでサーバーサイドのPreparedStatementを使う
jdbcのURLにuseServerPrepStmts=trueをつけるだけである。
Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/tokumaru?user=xxx&password=xxxx&useUnicode=true&useServerPrepStmts=true&characterEncoding=" + charEncoding)
簡単ですね。こうすることにって、U+00A5問題は発生しません。エスケープ自体どの時点でもしないわけですから。めでだしめでたし。
しかし、useServerPrepStmtsのデフォルト変更問題が
useServerPrepStmtsのここの説明ではデフォルトがtrueになっているが、これは上述の通り嘘である。ちなみに英語マニュアルをみるときちんとfalseになっている。これにはuseServerPrepStmtsの登場時(Connector/J 3.1.0)にはデフォルトがtrueだったが、5.0.5と5.1.0においてfalseに変更されたという経緯があるためのようだ。そしてなぜfalseにされたかということの背景を察すると、trueにすることの弊害もありそうで、手放しでこれをtrueにすることを勧めることが少しはばかられる。これについて詳しい方がいたらぜひ説明をお願いしたいところである。
- 新しい: 年末年始にやることりすと
- 古い: そろそろCakePHPについて一言言っておくか
コメント:0
トラックバック:2
- この記事のトラックバック URL
- https://blog.everqueue.com/chiba/2008/12/23/33/trackback/
- トラックバックの送信元リスト
- useServerPrepStmtsを使うのが根本解決だとはおもう。けど…? - へぼい日記 より
- trackback - id:kazuhookuのメモ置き場 より 2008/12/24 水曜日
MySQL+Java でサーバサイドプリペアードステートメン…
useServerPrepStmtsのここの説明ではデフォルトがtrueになっているが、これは上述の通り嘘である。 (中略) そしてなぜfalseにされたかということ (more…)
- trackback - mir the tritonn より 2008/12/24 水曜日
[MySQL][Connector/J][Java] Con…
ここ数日「MySQL + Connector/J(JDBCドライバ) + プリペアードステートメント」の話題がちらほら出ています。正確に把握はしていないですがSQLイ (more…)