30

休止状態を使用してアプリケーションを開発しています。ログインページを作成しようとすると、SQL インジェクションの問題が発生します。次のコードがあります。

@Component
@Transactional(propagation = Propagation.SUPPORTS)
public class LoginInfoDAOImpl implements LoginInfoDAO{

@Autowired
private SessionFactory sessionFactory;      
@Override
public LoginInfo getLoginInfo(String userName,String password){
    List<LoginInfo> loginList = sessionFactory.getCurrentSession().createQuery("from LoginInfo where userName='"+userName+"' and password='"+password+"'").list();
    if(loginList!=null )
        return loginList.get(0);
    else return null;   
          }
      }

このシナリオで SQL インジェクションを防ぐにはどうすればよいですか?loginInfo テーブルの create table 構文は次のとおりです。

create table login_info
  (user_name varchar(16) not null primary key,
  pass_word varchar(16) not null); 
4

5 に答える 5

27
Query q = sessionFactory.getCurrentSession().createQuery("from LoginInfo where userName = :name");
q.setParameter("name", userName);
List<LoginInfo> loginList = q.list();

他にも選択肢があります。mkyongのこの素敵な記事をご覧ください。

于 2012-12-31T13:48:36.170 に答える
20

SQL インジェクションを回避するには、名前付きパラメーターを使用する必要があります。また、(SQL インジェクションとは関係ありませんが、一般的なセキュリティとは関係ありません) 最初の結果を返さずにgetSingleResultを使用します。そのため、何らかの理由で複数の結果がある場合、クエリはNonUniqueResultExceptionで失敗し、ログインは成功しません。

 Query query= sessionFactory.getCurrentSession().createQuery("from LoginInfo where userName=:userName  and password= :password");
 query.setParameter("username", userName);
 query.setParameter("password", password);
 LoginInfo loginList = (LoginInfo)query.getSingleResult();
于 2012-12-31T13:51:00.760 に答える
10

SQL インジェクションとは何ですか?

SQL インジェクションは、不正な攻撃者がクエリ作成プロセスを操作して、アプリケーション開発者が最初に意図したものとは異なる SQL ステートメントを実行できる場合に発生します。

SQL インジェクション攻撃を防ぐ方法

解決策は非常にシンプルで簡単です。常にバインド パラメーターを使用していることを確認する必要があります。

public PostComment getPostCommentByReview(String review) {
    return doInJPA(entityManager -> {
        return entityManager.createQuery("""
            select p
            from PostComment p
            where p.review = :review
            """, PostComment.class)
        .setParameter("review", review)
        .getSingleResult();
    });
}

さて、このクエリをハッキングしようとしている人がいる場合:

getPostCommentByReview("1 AND 1 >= ALL ( SELECT 1 FROM pg_locks, pg_sleep(10) )");

SQL インジェクション攻撃が防止されます。

Time:1, Query:["select postcommen0_.id as id1_1_, postcommen0_.post_id as post_id3_1_, postcommen0_.review as review2_1_ from post_comment postcommen0_ where postcommen0_.review=?"], Params:[(1 AND 1 >= ALL ( SELECT 1 FROM pg_locks, pg_sleep(10) ))]

JPQL インジェクション

SQL インジェクションは、次の例に示すように、JPQL または HQL クエリを使用するときにも発生する可能性があります。

public List<Post> getPostsByTitle(String title) {
    return doInJPA(entityManager -> {
        return entityManager.createQuery(
            "select p " +
            "from Post p " +
            "where" +
            "   p.title = '" + title + "'", Post.class)
        .getResultList();
    });
}

上記の JPQL クエリはバインド パラメータを使用しないため、SQL インジェクションに対して脆弱です。

この JPQL クエリを次のように実行するとどうなるかを確認してください。

List<Post> posts = getPostsByTitle(
    "High-Performance Java Persistence' and " +
    "FUNCTION('1 >= ALL ( SELECT 1 FROM pg_locks, pg_sleep(10) ) --',) is '"
);

Hibernate は次の SQL クエリを実行します。

Time:10003, QuerySize:1, BatchSize:0, Query:["select p.id as id1_0_, p.title as title2_0_ from post p where p.title='High-Performance Java Persistence' and 1 >= ALL ( SELECT 1 FROM pg_locks, pg_sleep(10) ) --()=''"], Params:[()]

動的クエリ

文字列連結を使用してクエリを動的に作成するクエリは避ける必要があります。

String hql = " select e.id as id,function('getActiveUser') as name from " + domainClass.getName() + " e ";
Query query=session.createQuery(hql);
return query.list();

動的クエリを使用する場合は、代わりに Criteria API を使用する必要があります。

Class<Post> entityClass = Post.class;
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> query = cb.createTupleQuery();
Root<?> root = query.from(entityClass);
query.select(
    cb.tuple(
        root.get("id"),
        cb.function("now", Date.class)
    )
);


return entityManager.createQuery(query).getResultList();
于 2019-01-10T05:39:41.930 に答える
0

SQLInjection を防ぐために、一般的にストアド プロシージャを常に使用するようにしてください。準備済みステートメントを試す必要があります。

于 2012-12-31T13:50:27.760 に答える