天天看點

Hibernate防止SQL注入攻擊的方法如果在查詢字段中輸入單引号"'",則會報錯,這是因為輸入...Hibernate防止SQL注入攻擊的方法如果在查詢字段中輸入單引号"'",則會報錯,這是因為輸入

Hibernate防止SQL注入攻擊的方法如果在查詢字段中輸入單引号"'",則會報錯,這是因為輸入

Hibernate防止SQL注入攻擊的方法

  如果在查詢字段中輸入單引号"'",則會報錯,這是因為輸入的單引号和其他的sql組合在一起程式設計了一個新的sql,實際上這就是SQL注入漏洞,後來我在前台和背景都對輸入的字元進行了判斷。

  永遠也不要寫這樣的代碼:

  String queryString = "from Item i where i.description like '" + searchString + "'";

   List result = session.createQuery(queryString).list();

  如果使用者輸入:foo' and callSomeStoredProcedure() and 'bar' = 'bar,則你的程式在執行一個簡單查詢後,還會調用某個存儲過程,

  這樣你的程式就開了一個安全漏洞,如果使用者偶爾輸入了一個單引号,你的程式就可能報錯。

  永遠也不要把未經檢查的使用者輸入的值直接傳給資料庫!

  幸運的時有一個簡單的機制可以避免這種錯誤:

  JDBC在綁定參數時有一個安全機制,它可以準确的将那些需要轉義的字元進行轉義(escape),

  如上面的searchString,它被escape,不再作為一個控制字元了,而是作為被查詢的比對的字元串的一部分。(這裡指的是prepared statement,而是用普通的statment不行,我試過)。

  另外,如果我們使用參數綁定,還可以提高資料庫的執行效率,prepared statement語句被編譯一次後,被放在cache中,就不再需要編譯,可以提高效率。

  參數綁定有2種辦法:使用positional parameter或者named parameter。

  Hibernate支援JDBC樣式的positional parameter(查詢字元串中使用?),它同使用named parameter的效果一樣(查詢字元串中使用:)。

  使用named parameter

  使用named parameter,我們重新寫上面的查詢語句:

  String queryString = "from Item item where item.description like :searchString";

  冒号後面是一個named parameter,我們可以使用Query接口将一個參數綁定到searchString參數上:

  List result = session.createQuery(queryString)

           .setString("searchString", searchString)

           .list();

  因為searchString是一個使用者輸入的字元串,是以我們使用Query的setString()方法進行參數綁定,這樣代碼更清晰,更安全,效率更好!

  如果有多個參數需要被幫定,我們這樣處理:

  String queryString = "from Item item "

              + "where item.description like :searchString "

              + "and item.date > :minDate";

List result = session.createQuery(queryString)

         .setString("searchString", searchString)

          .setDate("minDate", minDate)

         .list();

  使用positional parameter

  如果你喜歡,也可以使用positional parameter:

  String queryString = "from Item item "

              + "where item.description like "

              + "and item.date > ";

List result = session.createQuery(queryString)

         .setString(0, searchString)

         .setDate(1, minDate)

         .list();

  這段代碼可讀性強不如上面的強,而且可維護性差,如果我們的查詢稍微改變一點,将第一個參數和第二個參數改變一下位置:

  String queryString = "from Item item "

              + "where item.date > "

              + "and item.description like ";

  這樣我們的代碼中涉及到位置的地方都要修改,是以我們強烈建議使用named parameter方式進行參數綁定。

  最後,在named parameter中可能有一個參數出現多次的情況,應該怎麼處理呢?

  String userSearch = "from User u where u.username like :searchString"

              + " or u.email like :searchString";

List result = session.createQuery(userSearch)

         .setString("searchString", searchString)

          .list();

  不要使用

  為了防止SQL注入,避免使用拼湊SQL語句的方式!!!

  在Hibernate+Spring中getHibernateTemplate()傳回的對象可以調用find(String queryString, Object value...Object value)來實作 named parameter。比如:

  view plain

  1. Date startTime = new Date(); 
  2. Date endTime = new Date(); 
  3. String queryString = "from SdmsRacalertLog as log where" + 
  4. " log.alertTime between :startTime and :endTime" ; 
  5. return getHibernateTemplate().find(queryString, startTime, endTime);