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

시큐어코딩(1) - SQL Injection

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

1. 정의


SQL 삽입(Improper Neutralization of Special Elements used in an SQL Command, SQL Injection)


데이터베이스와 연동된 웹 어플리케이션에서 입력된 데이터에 대한 유효성 검증을 하지 않을 경우, 공격자가 입력 폼 및 URL 입력란에 SQL 문을 삽입하여 DB로부터 정보를 열람하거나 조작할 수 있는 보안약점을 말함. 취약한 웹 어플리케이션에서는 사용자로부터 입력된 값을 필터링 과정없이 넘겨받아 동적 쿼리(Dynamin Query)를 생성한다. 이는 개발자가 의도하자ㅣ 않은 쿼리가 생성되어 정보유출에 악용될 수 있다.



2. 해결방법


- preparedStatement 클래스와 하위 메소드 executeQuery(), execute(), executeUpdate()를 사용하는 것이 바람직함.

- preparedStatement 클래스를 사용할 수 없는 환경이라면, 입력값을 필터링 처리할 후 사용한다. 필터링 기준은 SQL구문 제한, 특수문자 제한, 길이제한을 복합적으로 사용한다. 



3. 예제


========================== 안전하지 않은 코드의 예 ==========================


String tableName = props.getProperty("jdbc.tableName");

String name = props.getProperty("jdbc.name");

String query = "SELECT * FROM " + tableName + " WHERE Name =" + name;

stmt = con.prepareStatement(query);

rs = stmt.executeQuery();


============================================================================


외부로부터 tableName과 name의 값을 받아서 SQL 쿼리를 생성하고 있으며, name의 값으로 name' OR 'a'='a 를 입력하면 조작된 쿼리를 생성하는 문자열 전달이 가능하다.




============================== 안전한 코드의 예 =============================


String tableName = props.getProperty("jdbc.tableName");

String name = props.getProperty("jdbc.name");

String query = "SELECT * FROM ? WHERE Name = ? ";

stmt = con.prepareStatement(query);

stmt.setString(1, tableName);

stmt.setString(2, name);

rs = stmt.executeQuery();


============================================================================



이를 안전한 코드로 변환하려면 외부로부터 인자를 받는 prepareStatement 객체를 상수 스트링으로 생성하고, 인자 부분을 setString 등의 메소드로 설정하여, 외부의 입력이 쿼리문의 구조를 바꾸는 것을 방지하는 것이 필요하다.

반응형