본문 바로가기
04. 시큐어코딩

시큐어코딩(16) - SQL Injection: JDO

by 김덕환 2017. 11. 18.
반응형

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)이 질의문의 구조를 변경시키는 것을 방지할 수 있다.

반응형