Java EE6を学んで、JPAを学んで、JPQLを知ったとき
「Native Queryを使っていない場合、通常のSQLインジェクションされにくいよなぁ」
と個人的に思ったりしたことがあります(^^;JPQL構文で攻撃する人は少ないだろうなと。
でもそんな甘い考えが通じない世界なわけで、ちゃんと確認しておこうと思って以下やってみました。
以下のBookテーブル、レコードがあります。
ID |
書籍名 |
著者 |
1 |
Horikita |
MakiMaki |
2 |
Aoi |
Miyiazaki |
プログラムでは以下2つのメソッドを用意しました。
Prepared Statement(プレースホルダ、バインド変数)なしのJPQL
public int queryBookNotParameterized(String param){
Query query = em.createQuery("SELECT b FROM Book b WHERE b.title = '" + param + "'");
List<Book> books = query.getResultList();
return books.size();;
}
Prepared Statement(プレースホルダ、バインド変数)ありのJPQL
public int queryBookParameterized(String param){
Query query = em.createQuery("SELECT b FROM Book b WHERE b.title = :param");
query.setParameter("param", param);
List<Book> books = query.getResultList();
return books.size();
}
呼び出し
System.out.println(bookFacade.queryBookNotParameterized("' OR 'X' = 'X"));
System.out.println(bookFacade.queryBookParameterized("' OR 'X' = 'X"));
結果
プレースホルダなしの場合はJPQLインジェクションが成功してしまいました(^^;
入力した文字列(' OR 'X' = 'X)は通常よくあるSQLインジェクションと変わらないので、「JPQLだから大丈夫」とはいえない感じです。
同じこと考える人は当然いるわけで、海外にも情報ありました。
というわけで、ちゃんと考えて実装しないと、というお話でした(^^;