ikepyonのだめ人間日記

セキュリティに関することを書いていく予定。

動的に検索項目を指定したい場合のSQLインジェクション対策

バインド機能を使えば、ほぼすべてのSQLインジェクション脆弱性を防ぐことが出来るのは良く知られていると思いたい。しかし、アプリケーションの仕様によっては、検索項目やソート順を自由に変更したい場合がある。この場合、バインド機能では残念ながら対応できない。
そこで、以下のようなSQL文を組み立てることがあるのでは無いだろうか?

sql = "select * from table1 where " + (入力データ1) + "= ? order by " + (入力データ2) + ";";

「(入力データ*)」はここでブラウザから渡されたデータとする。この場合、いくらバインド機能使ってても、「(入力データ*)」の妥当性チェックがなされていなければSQLインジェクションが起こってしまう。
では、こうすればいいか?

sql = "select * from table1 where ? = ? order by ?;";

これは検索項目が文字データとし取り扱われるため、目的のことと違ってしまう。
検索項目を自由に指定できるようにし、安全にSQLを組み立てるには以下のようにすればよいと思う。まあ、入力値チェックをやってりゃいいんだけど、それを忘れたときのために・・・

param={"field1", "field2", "field3"};
sql = "select * from table1 where " + param[(入力データ1)] + "= ? order by " + param[(入力データ2)] + ";";

検索項目名、やソートキーはテーブルに存在するものしか存在しないのであるから、それらすべてを配列に格納し、配列の添え字をパラメータとして指定するようにすれば、数値チェックだけで済むので、非常に楽になると思う。
こういったロジックって使ってないことがたまにあるような?