2013-04-05 67 views
6

今天發現了一些使用Hibernate執行查詢的代碼。該查詢使用從表單提交的值。這讓我很好奇這種代碼是否「消毒」了它的輸入。Hibernate的createCriteria()是否清理輸入?

public List<School> search(String query) { 
    Session session = this.getCurrentSession(); 
    query = "%" + query + "%"; 
    Criteria criteria = session.createCriteria(getPersistentClass()); 
    criteria.createAlias("country", "a"); 
    Criterion nameCriterion = Restrictions.ilike("name", query); 
    Criterion cityCriterion = Restrictions.ilike("city", query); 
    Criterion countryCriterion = Restrictions.ilike("a.name", query); 
    Criterion criterion = Restrictions.or(Restrictions.or(nameCriterion, cityCriterion), countryCriterion); 
    criteria.add(criterion); 
    return criteria.list(); 
} 

這是安全嗎?

回答

4

Hibernate標準查詢在Sql注入方面安全無比,因爲它們在執行任何獲取時都將字符串作爲參數傳遞。即使如此,除非通過字符串文字構建查詢,否則Hql是安全的。

有關更多詳細信息,請查看通過切換hibernate sql日誌記錄在數據庫級別發起的查詢。

+0

恰巧我只是看着生成的SQL(這是什麼提醒我檢查這些答案),你是絕對正確的。 – Marvo 2013-04-05 23:05:50

5

如果您認爲SQL注入攻擊,那麼是的,Hibernate Criteria API是安全的。

它將通過首先編譯它從指定的查詢字段並且僅在應用查詢參數(它應該使用經典的PreparedStatement)之後生成基礎查詢。這樣JDBC驅動程序就會知道查詢的哪一部分是字段,哪一部分是參數。然後司機會小心地清理參數。

如果您需要在那裏放置參數,您應該注意應用於Criteria上的SQL限制。例如

String vulnerable = //parameter from user interface 

criteria.add(
    Restrictions.sqlRestriction("some sql like + vulnerable") //vulnerable 

criteria.add(
    Restrictions.sqlRestriction("some sql like ?", 
       vulnerable, Hibernate.STRING)) //safe 

在這種情況下,vulnerable參數可以在該查詢字段的一部分,並通過JDBC驅動程序檢查在正常漏洞的SQL查詢來繞過「泄漏」。

+0

啊,限制上的優點。 – Marvo 2013-04-05 23:06:55

+0

希望我能接受這兩個答案。 Ankit首先回答,所以我給了他對號。 – Marvo 2013-04-05 23:08:59

1

Hibernate有助於消毒輸入,但消毒輸入不被認爲是防止SQL注入攻擊的最佳實踐。隨着您的代碼隨着時間的推移而發展,您將需要記住在您的數據庫和客戶端應用程序發生變化時更改您的Hibernate衛生設施;這留下了大量的錯誤空間,任何一個錯誤都可能危及你的數據庫。

要防止SQL注入攻擊,最好使用預準備語句。在準備好的語句中,您的客戶端應用程序將發出非SQL請求,並讓您的服務器生成您的SQL語句。

例如,如果用戶想要在這個城市「達拉斯」的所有用戶,那麼您的客戶端應用程序應該類似於用戶名的請求等於「達拉斯」,然後你的服務器可以生成:

SELECT * FROM users WHERE name='Dallas'