SQL삽입 취약점 개요
데이터베이스(DB)와 연동된 응용프로그램에서 입력된 데이터에 대한 유효성 검증을 하지 않을 경우, 공격자가 입력 값을 조작하여 SQL 문에 삽입하여 DB로부터 정보를 열람하거나 조작할 수 있는 보안 취약점
다양한 입력 데이터
웹 애플리케이션의 양식을 통해 입력받은 사용자의 입력값, 공격자에 의해 수정된 쿠키값
공격자에 의해 수정된 HTTP헤더와 같은 서버 변수
SQL 삽입 취약점 공격 패턴
SELECT * FROM USERS WHERE ID='ADMIN' AND PASSWD='tst321##'
SQL 삽입 취약점을 가지는 쿼리 구조
String id = request.getParameter("id)";
-->
String sql = "select * from users where id='"+id+"'";
-->
select * from users where id='test'
-->
쿼리실행
=> 구문분석 -> 컴파일 -> 명령어 -> 실행
SQL 삽입 취약점을 가지지 않는 쿼리 구조
String id = request.getParameter("id");
-->
"select * from users where id=?"
-->
setString(1, id)
-->
쿼리 실행
SQL삽입 취약점을 대응하는 방법
개발자가 입력값에 대해 인코딩된 입력값은 디코딩 한 후, 화이트리스트 작성된 사용 가능한 값을 이용하여 유효성 검사를 한 뒤, 매개 변수화된 쿼리를 사용하는 준비된 SQL문(정적쿼리)를 사용
데이터베이스에 접속하는 계정 권한을 최소한으로 제한
저장 프로시저도 공격에 많이 사용되므로 불필요한 저장 프로시저를 제거
=> 필터링 수행후 사용
SQL삽입 - JDBC API 사용
String query = "SELECT * FROM users WHERE userid ='"+userid+"'"+
"AND password='"+password+"'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
=> 구문 -> 컴파일 -> 실행
String query = "SELECT * FROM users WHERE userid=? AND password=?";
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setString(1, userid);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
=> 분석 -> 컴파일 -> 명령어
1. 외부입력값을 동적으로 생성해서 실행하는 SQL문에 사용하는 경우 공격자가 의도하는 SQL문이 실행될 수 있다.
2. 쿼리명령을 미리 만들어서 외부입력값을 파라미터로 매핑해서 실행하는 정적인 쿼리 구조를 사용하는 것이 안전하다.
3. 동적으로 쿼리를 생성해서 사용해야 한다면 입력값을 안전하게 필터링해서 사용하자.