2007年7月 7日
SQLインジェクション対策
今更だが、SQLインジェクション対策の話。
対策方法はただひとつ。SQL文を生成(文字列連結)するときに入力文字列をエスケープすること。
SQL文を生成した後でエスケープしようとしても、そこにある文字がエスケープすべき文字なのかどうかは判別不可能だ。また、SQLインジェクションが発生しているかどうかを検知するのも不可能だ。構文エラーになっていたら検知できるが、それは仮に実行してしまってもエラー終了するだけで大きな副作用は発生しない。また、実行できるSQL文になっていたら、それがSQLインジェクションなのかどうかは機械的には分からない。
「マルチステートメントなら実行できない」といった程度の対策なら可能だ。しかし、SQLインジェクションが成立するにはマルチステートメントが必須なわけではないので、それで対策完了というわけには行かない。
で、連結時にエスケープしようと思うのだが、これも結構厄介だ。調べれば調べるほど、危険な文字の存在に気づかされる。UTF-8などのわけわからない空間から攻撃されると困ってしまう。
そこで、普通は prepared statement (プリペアドステートメント:準備された文) あるいは parameterized query (パラメタライズドクエリ)を用いる。
これなら、何をブチ込んでもそれなりに解釈されて、そのままDBのフィールドにブチ込んでくれる。
もちろん、' (シングルクオーテーション)などもそのまま格納可能だ。
大量の音楽に対して 「80's J-POP」みたいなカテゴリをつけたいときなどには非常に重宝する。
それでも例外がひとつあり、LIKE句の時だけは % と _ を変換しなければならない。
参考:第2章 セキュアDBプログラミング [2-1.]SQL組み立て時の引数チェック
このエントリーのトラックバックURL:
http://weblog.rukihena.com/mt/mt-tb.cgi/699