PDOにおけるSQLインジェクションの危険性とその回避についてまとめ

PHPのデータベース・アクセス・ライブラリPDOは、DB接続時の文字エンコーディング指定ができないため、文字エンコーディングの選択によっては、プレースホルダを使っていてもSQLインジェクション脆弱性が発生しうるという徳丸氏のブログ内容に対し、識者がその回避方法について試し、報告しています。
8
徳丸 浩 @ockeghem

.@nihen ありがとうございます。当方でも試します…しかし、こういう情報、よく調べないとわからないですよね

2010-07-01 12:00:31
Moriyoshi Koizumi @moriyoshit

@ockeghem そうです。パーサを通過した後のエスケープは、すべて mysql_real_escape_string() 任せです。

2010-07-01 12:32:30
徳丸 浩 @ockeghem

.@haruyama PDOの件で、私が一番問題だと思うのは、「PDO 文字化け」で検索すると、間違った対処方法ばかりが出てくるわけですよ。だから、ああして問題提起することも必要なのではないかなと思うわけです

2010-07-02 07:15:48
HARUYAMA Seigo @haruyama

前半は同意です. しかしあのエントリはさらなる誤解を発生させちゃうのでは? @ockeghem: PDOの件で、私が一番問題だと思うのは、「PDO 文字化け」で検索すると、間違った対処方法ばかりが出てくるわけですよ。だから、ああして問題提起することも必要なのではないかな(以下略

2010-07-02 07:51:52
HARUYAMA Seigo @haruyama

.@ockeghem xamppやGNU/Linuxのパッケージで入るMySQLはcharsetが設定していないことが多い(未調査), かつPDOのデフォルトはなんちゃってプリ...なので, そのままだとPDOで問題があるよという話だと思いますが,前提が伝わらないように思えます.

2010-07-02 08:00:15
徳丸 浩 @ockeghem

.@haruyama その点については、追記で補足しましたが、どうでしょうか?

2010-07-02 08:02:31
HARUYAMA Seigo @haruyama

.@ockeghem 1. システム内で一環したエンコーディングを利用する. かつエンコーディング設定をきちんと行なう. 2. どうしても一貫したエンコーディングを利用できない場合, クライアントからシステム全体のエンコーディング設定を変更する という流れがまずあるのがいいかと.

2010-07-02 08:05:47
徳丸 浩 @ockeghem

.@haruyama 私が試したのはwindowsとCentosですが、明示的にmy.cnfのパス名渡さないとだめでした

2010-07-02 08:06:13
徳丸 浩 @ockeghem

@haruyama同意です。そこは書いてないですね

2010-07-02 08:07:30
徳丸 浩 @ockeghem

.@haruyama ですね。あれを書いた時点では、明示的にcharset渡す方法がないと思っていたのでああいう書き方になりました。補足しときます。

2010-07-02 08:15:16
HARUYAMA Seigo @haruyama

.@ockeghem PDOはシステムのmy.cnfは読んでますが, デフォルトでは[client]セクションを見てなかったです. PDO::MYSQL_ATTR_READ_DEFAULT_GROUP を指定すると 指定したセクションとclientを読むようです.

2010-07-02 08:26:05
HARUYAMA Seigo @haruyama

.@ockeghem またmysqlnd をつかっている場合にはシステムのmy.cnf は読まないようです. ここらへんはちゃんと理解してませんでした.

2010-07-02 08:26:52
HARUYAMA Seigo @haruyama

.@ockeghem 安全なSQLの呼び出し方の続編で, 各構成にてサーバ・クライアントで一貫したエンコーディングを使う場合はこう設定する, そうでない場合にこうエンコーディングを指定するというのがあるとよさそうですね.

2010-07-02 08:30:41
徳丸 浩 @ockeghem

.@haruyama PDOの文字化け回避策としてのskip-character-set-client-handshakeは私もググって見つけましたが、バッドノウハウですよね。でも、そのブログエントリにはset namesより安全なように書いてありました

2010-07-02 09:54:18
HARUYAMA Seigo @haruyama

.@ockeghem そうですね. 結局設定ファイルで指定しないといけなさそうです.

2010-07-02 10:03:19
徳丸 浩 @ockeghem

そうですね。材料はかなり集めましたが、まとめきれなかった面があります RT @haruyama: .@ockeghem 安全なSQLの呼び出し方の続編で, 各構成にてサーバ・クライアントで一貫したエンコーディングを使う場合はこう設定する, そうでない場合に…

2010-07-02 10:43:07
徳丸 浩 @ockeghem

MDB2もMySQLはイマイチですね。静的プレースホルダは使われますが、バインドをテキスト形式でやっていて、Shift_JISを指定するとエラーになる(別の問題との合わせ技)・・・トホホ

2010-07-02 10:44:30
Moriyoshi Koizumi @moriyoshit

PDOの件は変更を追っておらず、常にエミュレーションが働くようになっていたと知りませんでした。この挙動はおかしいので、直させようかと思います。

2010-07-02 10:50:19
mataka @mataka

PHPに引導を渡して欲しいです。RT @ockeghem: この調子でケチをつけていくと使えるものがなくなって「ぼくがPHPを採用しなかったわけ」となってしまいかねないので、どこかで落としどころを探さねば

2010-07-02 11:01:40
徳丸 浩 @ockeghem

素晴らしいです。接続時のcharset指定もぜひできるようにしていただきたいです。 RT @moriyoshit: PDOの件は変更を追っておらず、常にエミュレーションが働くようになっていたと知りませんでした。この挙動はおかしいので、直させようかと思います。

2010-07-02 11:02:32
CHIBA Masahiro @nihen

この辺も参考になるかとhttp://bit.ly/9VXVYh http://bit.ly/dpGqwN @moriyoshit PDOの件は変更を追っておらず、常にエミュレーションが働くようになっていたと知りませんでした。この挙動はおかしいので、直させようかと思います。

2010-07-02 12:05:08
Moriyoshi Koizumi @moriyoshit

@nihen ほうほう。ありがとうございます。すごい参考になりました。

2010-07-02 12:18:26
Moriyoshi Koizumi @moriyoshit

サーバ側の問題なんだからクライアントであれこれするのは筋が通ってないわけだけど、実務的にはねえ。

2010-07-02 12:18:50