7

今日、Hibernate を使用してクエリを実行するコードに出会いました。クエリは、フォームから送信された値を使用します。この種のコードがその入力を「サニタイズ」するかどうかについて、私は興味をそそられました。

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

3 に答える 3

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パラメーターはクエリ フィールド部分に「漏れ」、通常の脆弱な SQL クエリと同様に、JDBC ドライバー チェックによってバイパスされる可能性があります。

于 2013-04-05T20:09:48.460 に答える
5

Hibernate Criteria クエリは、フェッチの実行中にパラメーターとして文字列を渡すため、Sql インジェクションに関して静かに安全です。さらに、文字列リテラルを使用してクエリを作成しない限り、Hql は静かに安全です。

詳細については、hibernate sql logging をオンにして、データベース レベルで実行されるクエリを確認する必要があります。

于 2013-04-05T19:48:40.693 に答える
1

Hibernate は入力のサニタイズに役立ちますが、入力のサニタイズは SQL インジェクション攻撃を防ぐためのベスト プラクティスとは見なされません。時間の経過とともにコードが開発されるにつれて、データベースとクライアント側アプリケーションの変更に合わせて Hibernate サニテーションを変更することを覚えておく必要があります。これにより、エラーが発生する余地が大きくなり、1 つの間違いでデータベースが危険にさらされる可能性があります。

SQL インジェクション攻撃を防ぐには、準備済みステートメントを使用することをお勧めします。プリペアド ステートメントでは、クライアント側アプリケーションが非 SQL 要求を行い、サーバーに SQL ステートメントを生成させます。

たとえば、ユーザーが都市 "Dallas" のすべてのユーザーを必要とする場合、クライアント側アプリケーションはusername equals "Dallas"と同様の要求を行う必要があり、サーバーは次を生成できます。

SELECT * FROM users WHERE name='Dallas'
于 2014-10-16T17:16:01.383 に答える