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 등의 메소드로 설정하여, 외부의 입력이 쿼리문의 구조를 바꾸는 것을 방지하는 것이 필요하다.
'04. 시큐어코딩' 카테고리의 다른 글
시큐어코딩(6) - Open Redirect (0) | 2017.11.15 |
---|---|
시큐어코딩(5) - Unrestricted Upload of File with Dangerous Type (0) | 2017.11.15 |
시큐어코딩(4) - OS Command Injection (0) | 2017.11.15 |
시큐어코딩(3) - Cross-site Scripting (0) | 2017.11.14 |
시큐어코딩(2) - Resource Injection (0) | 2017.11.14 |