1. 정의
SQL 삽입공격 : JDO (SQL Injection: JDO)
외부의 신뢰할 수 없는 입력을 적절한 검사 과정을 거치지 않고 JDO(Java Data Objects) API의 SQL 또는 JDOQL 질의문 생성을 위한 문자열로 사용하면, 공격자가 프로그래머가 의도하지 않았던 문자열을 전달함으로써 질의문의 의미를 왜곡시키거나 그 구조를 변경하여 임의의 질의 명령어를 수행할 수 있다.
2. 해결방법
- JDO 질의문의 생성시에는 상수 문자열만을 사용하고 Query.execute(...) 실행시에는 인자값을 전달하는 방법(Parameterize Query)을 사용한다.
3. 예제
========================== 안전하지 않은 코드의 예 ==========================
public class ContactItem implements ContactDAO
{
public List<Contact> listContacts()
{
PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
String query = "select from " + Contact.class.getName();
try
{
Properties props = new Properties();
String fileName = "contacts.txt";
FileInputStream in = new FileInputStream(fileName);
if( in != null ) { props.load(in); }
in.close();
// 외부로 부터 입력을 받는다.
String name = props.getProperty("name");
if( name != null )
{
query += " where name = '" + name + "'";
}
}
catch (IOException e) { ... }
// 외부 입력값이 JDO 객체의 인자로 사용된다.
return (List<Contact>) pm.newQuery(query).execute();
}
}
============================================================================
위의 예제에서는 공격자가 외부의 입력(name) 값을 name'; DROP MYTABLE; -- 로 주게 되면, 다음과 같은 질의문이 수행되어 테이블이 삭제된다.
(SELECT col1 FROM MYTABLE WHERE name = 'name' ; DROP MYTABLE; --')
============================== 안전한 코드의 예 =============================
public class ContactItem implements ContactDAO
{
public List<Contact> listContacts()
{
PersistenceManager pm = getPersistenceManagerFactory().getPersistenceManager();
String query = "select from " + Contact.class.getName();
String name = "";
try
{
Properties props = new Properties();
String fileName = "contacts.txt";
FileInputStream in = new FileInputStream(fileName);
props.load(in);
// 외부로 부터 입력을 받는다.
name = props.getProperty("name");
// 입력값을 점검한다.
if (name == null || "".equals(name)) return null;
query += " where name = ?";
}
catch (IOException e) { ... }
javax.jdo.Query q = pm.newQuery(query);
// Query API의 인자로 사용한다.
return (List<Contact>) q.execute(name);
}
}
============================================================================
위의 코드처럼 외부 입력 부분을 ?로 설정하고(Parameterize Query), 실행시에 해당 인자값이 전달되도록 수정함으로써 외부의 입력(name)이 질의문의 구조를 변경시키는 것을 방지할 수 있다.
'04. 시큐어코딩' 카테고리의 다른 글
시큐어코딩(18) - SQL Injection: mybatis Data Map (0) | 2017.11.18 |
---|---|
시큐어코딩(17) - SQL Injection: Persistence (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 |
시큐어코딩(13) - HTTP Response Splitting (0) | 2017.11.17 |