myfinderの技術や周辺的活動のblog

2008年12月6日土曜日

SQLを生成するときに文字列連結しちゃいけない理由

プログラムでSQLを書くときに

String sql = "select *
from TABLE
where COLUMN_ID=" + input;

とか書いてしまうことが初学のときにあった。
これはチョーよくない。

これだとinputに「1 or 0=0」が入ってたりしたときに危険。
なんで危険なのかというと、SQLが

select * from TABLE where COLUMN_ID=1 or 0=0

となってしまう。
こうなると、「0=0」が常に真になるので、どんなクエリでもwhereの条件に当てはまってしまう。

このSQLではデータが全件返ってきてしまい、指定されたID以外のデータが表示されてしまう可能性がある。
こういうのを「SQLインジェクション」って呼ぶ。

じゃあどうやって回避するのかというと、JavaならPreparedStatementを使うのがよくあるやり方。

String sql = "select *
from TABLE
where COLUMN_ID=?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, input);

setString(1,input)の1というのが、sql中で最初に出てくる?にあたる。
0じゃないのが気になるところ。

ただ、like演算子のときに使う「%」とか「_」は自動的に対策されないので、replaceAllメソッドとかでエスケープする必要がある。

0 件のコメント: