[SQL] 어떻게 JPA와 최대 절전 모드로 SQL 주입을 방지하기 위해?
SQL어떻게 JPA와 최대 절전 모드로 SQL 주입을 방지하기 위해?
나는 최대 절전 모드를 사용하여 응용 프로그램을 개발하고있다. 나는 로그인 페이지를 만들려고 할 때, 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;
}
}
? 어떻게 다음과 같이 LOGININFO 테이블의 테이블 구문은 생성이 시나리오에서 SQL 주입을 방지 할 수 있습니다 :
create table login_info
(user_name varchar(16) not null primary key,
pass_word varchar(16) not null);
해결법
-
==============================
1.
Query q = sessionFactory.getCurrentSession().createQuery("from LoginInfo where userName = :name"); q.setParameter("name", userName); List<LoginInfo> loginList = q.list();
당신은 너무 다른 옵션이 mkyong에서이 좋은 문서를 참조하십시오.
-
==============================
2.당신은 SQL 주입을 방지하기 위해 명명 된 매개 변수를 사용해야합니다. 또한 첫 번째 결과를 반환하지만 어떤 이유 하나 개 이상의 결과가 그렇다면 getSingleResult를 사용하지 않는 (아무것도 SQL 주입하지만, 일반적으로 보안 할 수 없습니다), 쿼리가 NonUniqueResultException에 실패하고 로그인이 성공적인되지 않습니다
당신은 SQL 주입을 방지하기 위해 명명 된 매개 변수를 사용해야합니다. 또한 첫 번째 결과를 반환하지만 어떤 이유 하나 개 이상의 결과가 그렇다면 getSingleResult를 사용하지 않는 (아무것도 SQL 주입하지만, 일반적으로 보안 할 수 없습니다), 쿼리가 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();
-
==============================
3.이 솔루션은 매우 간단하고 직선적이다. 당신은 당신이 항상 바인드 매개 변수를 사용하는 것이 확인해야합니다 :
이 솔루션은 매우 간단하고 직선적이다. 당신은 당신이 항상 바인드 매개 변수를 사용하는 것이 확인해야합니다 :
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 또는 HQL 쿼리를 사용할 때 다음의 예에 의해 입증으로 SQL 주입도 일어날 수있다 :
public List<Post> getPostsByTitle(String title) { return doInJPA(entityManager -> { return entityManager.createQuery( "select p " + "from Post p " + "where" + " p.title = '" + title + "'", Post.class) .getResultList(); }); }
이 SQL 인젝션에 취약하므로 JPQL 쿼리 위, 바인드 매개 변수를 사용하지 않습니다.
나는이 같은이 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();
동적 쿼리를 사용하려면, 대신 조건 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) ) );
반환 entityManager.createQuery (쿼리) .getResultList ();
자세한 내용은이 문서를 확인하십시오.
-
==============================
4.내가 검색처럼 쿼리의 사용 가능한 독특한 SQL 주입입니다 여기에 추가하고 싶습니다.
내가 검색처럼 쿼리의 사용 가능한 독특한 SQL 주입입니다 여기에 추가하고 싶습니다.
우리는 다음과 같이 우리가 쿼리 문자열 있다고 가정 해 봅시다 :
queryString = queryString + " and c.name like :name";
이름 매개 변수를 설정하는 동안, 대부분은 일반적으로 이것을 사용합니다.
query.setParameter("name", "%" + name + "%");
이제, "1 = 1"이 때문에 TypedQuery의 주입 할 수 없으며 최대 절전 모드는 기본적으로 처리합니다 같은 전통적인 매개 변수 위에서 언급 한 바와 같이.
그러나 때문에 밑줄의 사용이다 LIKE 쿼리 구조의 여기 가능한 독특한 SQL 주입이있다
이제, 우리의 시나리오의 경우 우리가 설정 한 경우
등등.
이상적인 수정 :
___ \ _ \ _ \ _ (3 개 당량 원료 밑줄)이 될 것이다
마찬가지로, 그 반대의 쿼리는 %의 필요가 탈출 할 수있는 주사가 발생합니다.
-
==============================
5.우리는 항상 저장 프로 시저가 불가능 SQL 인젝션 .. 경우에 방지하기 위해 일반적으로 저장 프로 시저를 사용하려고한다 우리는 문 준비를 위해 시도해야합니다.
우리는 항상 저장 프로 시저가 불가능 SQL 인젝션 .. 경우에 방지하기 위해 일반적으로 저장 프로 시저를 사용하려고한다 우리는 문 준비를 위해 시도해야합니다.
from https://stackoverflow.com/questions/14102334/how-to-prevent-sql-injection-with-jpa-and-hibernate by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 어떻게 SQL 쿼리 결과 집합의 바이트 크기를 얻으려면? (0) | 2020.05.23 |
---|---|
[SQL] field.types와 RMySQL dbWriteTable (0) | 2020.05.23 |
[SQL] 는 SQL 서버에 업데이트 된 행 I의 ID를 얻기 (0) | 2020.05.23 |
[SQL] 어떻게 SQL 데이터베이스에 아랍어 문자를 삽입하려면? (0) | 2020.05.23 |
[SQL] java.sql.Date로 변환 문자열 일 [중복] (0) | 2020.05.23 |