1. 정의
SQL 삽입공격 : Persistence(SQL Injection: Persistence)
J2EE Persistence API를 사용하는 응용프로그램에서 외부 입력에 대한 검증없이 질의문에 그대로 사용하면, 질의문의 의미를 왜곡시키거나 그 구조를 변경하여 임의의 질의 명령어가 수행될 수 있다.
2. 해결방법
- 외부의 입력이 질의문의 구조를 변경할 수 없는 인자화된 질의문(Parameterize Query)을 사용한다. 즉, 질의문의 생성시 상수 문자열만을 사용하고 javax.persistence.Query.setParameter() 메소드를 사용하여 인자값을 설정하는 방법을 사용한다.
3. 예제
========================== 안전하지 않은 코드의 예 ==========================
public List<?> getAllItemsInWildcardCollection()
{
EntityManager em = getEntityManager();
List<ItemListner> r_type = null;
try
{
Properties props = new Properties();
String fileName = "conditions.txt";
FileInputStream in = new FileInputStream(fileName);
props.load(in);
// 외부로 부터 입력을 받는다.
String id = props.getProperty("id");
// 외부 입력 값이 query의 인자로 사용이 된다.
Query query = em.createNativeQuery("SELECT OBJECT(i) FROM Item i WHERE i.itemID > " + id);
List<ItemListner> items = query.getResultList();
}
return r_type;
}
============================================================================
위의 예제에서 공격자가 외부의 입력(id)의 값으로 foo'; DROP MYTABLE; -- 을 주게 되면, 다음과 같은 질의문이 실행되어 테이블이 삭제된다.
(SELECT col1 FROM MYTABLE WHERE name = 'foo' ; DROP MYTABLE; --')
============================== 안전한 코드의 예 =============================
public List<?> getAllItemsInWildcardCollection()
{
EntityManager em = getEntityManager();
List<ItemListner> r_type = null;
try
{
Properties props = new Properties();
String fileName = "conditions.txt";
FileInputStream in = new FileInputStream(fileName);
props.load(in);
// 외부 입력값을 받는다.
String id = props.getProperty("id");
// 입력값을 검사한다.
if (id == null || "".equals(id)) id = "itemid";
// Query문을 작성한다.
Query query = em.createNativeQuery("SELECT OBJECT(i) FROM Item i WHERE i.itemID > :id");
query.setParameter("id", id);
List<ItemListner> items = query.getResultList();
}
return r_type;
}
============================================================================
위의 코드처럼 인자를 받는 질의문(query)을 생성하고, 인자값을 설정하여 실행하도록 한다. 이를 통해 외부의 입력이 질의문의 구조를 변경시키는 것을 방지할 수 있다.
'04. 시큐어코딩' 카테고리의 다른 글
시큐어코딩(19) - LDAP Manipulation (0) | 2017.11.22 |
---|---|
시큐어코딩(18) - SQL Injection: mybatis Data Map (0) | 2017.11.18 |
시큐어코딩(16) - SQL Injection: JDO (0) | 2017.11.18 |
시큐어코딩(15) - Reliance on Untrusted Inputs in a Security Decision (0) | 2017.11.18 |
시큐어코딩(14) - Integer Overflow or Wraparound (0) | 2017.11.17 |