SQL或HQL先行編譯語句,能夠防止SQL注入,但是不能處理%和_特殊字元,hqlsql

來源:互聯網
上載者:User

SQL或HQL先行編譯語句,能夠防止SQL注入,但是不能處理%和_特殊字元,hqlsql

最近項目在做整改,將所有DAO層的直接拼接SQL字串的代碼,轉換成使用先行編譯語句的方式。個人通過寫dao層的單元測試,有以下幾點收穫。

dao層代碼如下

//使用了先行編譯sqlpublic List<IndvConfigModel> selectConfigBySuffix(String suffix){        String hql = "from IndvConfigModel where configKey like '%'||?||'%'";        return this.selectConfigByHQL(hql, new Object[]{suffix});}


單元測試代碼和執行結果如下:

@Testpublic void testLike(){    List<IndvConfigModel> list = dao.selectConfigBySuffix("picQual");    Assert.assertEquals(list.size(), 2);// 1.true    list = dao.selectConfigBySuffix("picQua%");    Assert.assertEquals(list.size(), 2);// 2.true        list = dao.selectConfigBySuffix("pic'Qual");    Assert.assertEquals(list.size(), 0);//3. true}

1、第一個斷言是true,說明上面的做法,的確能夠起到模糊查詢的效果 
 
2、第二個斷言是true,說明%被認為是模糊比對,並沒有被oracle看成普通的字元。這說明先行編譯語句,是不能處理參數值中的特殊字元的。遇到%和_這種資料庫模糊查詢的特殊字元,需要使用者自己轉義.
  
3、第三個斷言沒有報異常。說明:先行編譯語句已經對oracle的特殊字元單引號,進行了轉義。即將單引號視為查詢內容,而不是字串的分界符。
 
由於SQL注入其實就是藉助於特殊字元單引號,產生or 1= 1這種格式的sql。先行編譯已經對單引號進行了處理,所以可以防止SQL注入


java的先行編譯語句集可以防止所有sql注入

是的,先行編譯有個類是PreparedStatement.
這個類的對象是通過參數?來傳值的
例:
String sql = "select * from table where id = ?";
Connection con = .....///這裡得到是資料庫的串連
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1,id);//這裡的資料庫語句所用到的參數要被設定的,如果你傳入了錯的值,或不同類型的值,它在插入到資料庫語句中會編譯不通過,這也就防止了SQL注入。
 
hibernate可以否防止sql注入

很可惜,如果你是組合hql字串的話,是防止不了的,要防止的話,也要用預留位置,比如
query=session.createQuery("select count(*) from CpUser where id = :id and password = :password");
...
query.setParameter("id".userForm.getId());
...
如果你不想這麼做的話,就要自己寫一個filter,自動把所有的request參數值處理一下,如特殊字元前加上\,就不會有注入錯誤了
 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.