はじめに
お疲れ様です。Tomita Kentaroと申します。今回は、SQLインジェクションについて考える機会があったため、その対策などを備忘録として、この記事にまとめます。
対策していないコード
まず、対策していないコードを見てみましょう。直接id
とpass
を格納しています。
val query = entityManager
.createQuery("SELECT * FROM t WHERE id = $id AND pass = $pass")
何がダメなのか?
例えば、$id
にa
、$pass
に' OR 'X' = 'X
という文字を入れてみましょう。
SELECT * FROM t WHERE id = 'a' AND pass = '' OR 'X' = 'X'
すると、パスワードがわからなくても、'X' = 'X'
が真のため情報を取得できます。
対策してあるコード
では、対策してあるコードを見てみましょう。今回は、プレースホルダを使って対策しています。プレースホルダの部分にはsetParameter
関数で値をセットします。
val query = entityManager
.createQuery("SELECT * FROM t WHERE id = :id AND pass = :pass")
.setParameter(":id", id)
.setParameter(":pass", pass)
何が良いのか?
調べてみたら、プレースホルダを使うことで、SQL文とプレースホルダが別々にコンパイルされるため、SQLインジェクションができない様です。プレースホルダを使うことで、SQL文自体のコンパイルの時は、以下の様な文になります。
SELECT * FROM t WHERE id = ? AND pass = ?
最後に
この機会に、SQLインジェクション対策は、しっかり気をつけようと思いました。もしかしたら、記事の内容に誤りがある可能性もあるので、もし間違いがあればコメントなどでお知らせください。最後に、参考文献のURLを記載いたします。
・JPQLインジェクションを確認してみました - Challenge Engineer Life !
・Oracleにおけるバインド変数の利用 #SQL - Qiita