概要
ネット上のNode.js(Express)でPostgreSQL使うサンプルは、SQLインジェクションを考慮していないものが多く、注意が必要です。
例えばフォームに入力された値をそのままDBにINSERTしたり、さらにそれをherokuで公開させたりしています。
このような状態で公開すると、第三者が簡単にSQLインジェクションを行いDBを破壊される可能性があります。知っていればできる対策なので、きちんと行いましょう。
対策
SQL文へのパラメータの渡し方にプレースホルダーを使いましょう。
対策してない場合
まず未対策のコードだとどうなるんでしょうか。
var queryString= client.query("insert into mydata (name, mail, memo) " +
"values ('" + name_str + "','" + mail_str + "','" + memo_str + "');");
フォームからはname_str, mail_str, memo_strがテキストエリアに入力されて渡されると仮定します。このあと、queryStringを使用してDBにクエリを発行します。
さてこのとき、name_strに以下の文字列を入力するとどうなるでしょう?
','','');INSERT INTO mydata (name, mail, memo) values ('injection', 'injection', 'injection');--
これを変数に代入して作られるSQL文を見てみます。
insert into mydata (name, mail, memo) values ('','','');INSERT INTO mydata (name, mail, memo) values ('injection', 'injection', 'injection');--,'','');
空のデータのINSERTが成功すると、開発者の意図しないSQLが流されてしまいます。
この例ではINSERTですが、権限があればDROPだとかCREATEとかだってできちゃいます。
対策する
SQLに渡されるパラメータをプレースホルダを使って書きます。
var queryString= client.query("insert into mydata (name, mail, memo) " +
"values ('$1, $2, $3');"
,[name_str, mail_str, memo_str]);
values内の$1
,$2
,$3
がプレースホルダです。
こうすることでname_strにSQLとして解釈可能なものが入れらても、発行した際にエラーとなり、インジェクションを防ぐことができます。
まとめ
SQLインジェクションは、対策を怠ると開発側が責任を負わされるケースがあります。知っていれば対策できることなので、しっかり対策しましょう。