구현단계 보안약점 중 SQL Injection에 대해 다뤄보고자 합니다.

구현단계 보안약점 유형 및 세부항목 소개( http://jwprogramming.tistory.com/262?category=682224 )


1. SQL Injection

1) SQL이란?

- 관계형 데이터베이스(MySQL, Oracle, Maria DB 등) 관리 시스템의 데이터를 관리하기 위해 설계된 프로그래밍 언어입니다.


그렇다면, 이 SQL Injection 공격은 무엇일까요?


대부분의 정보시스템은 데이터베이스를 사용하여 어떠한 데이터(사용자 ID, P/W, 시스템 관련 데이터 등)를 저장하고 있을 것입니다. 이렇게 DB운영자가 데이터베이스 시스템을 사용하기 위해서는 위의 SQL 구문을 이용하여 데이터베이스에 접근하여 데이터를 조회, 삽입, 삭제, 업데이트 등 일련의 행동을 할 것입니다.


예를 들어, SQL을 통해 아래와 같이 items 테이블로부터 사용자의 이름 등의 정보를 조회한다고 가정합니다.

string userName = request.getParameter("username");

string query = "SELECT * FROM items where owner = '"+ userName + "'"; 

위에서 userName은 외부에서 입력받아서 데이터베이스에 접근하게 되는 데이터일 것입니다.

만약 이 userName로 입력받는 값에 대하여 적절한 검증이 이루어지지 않은 채로 아래의 값이 들어오면 어떻게 될까요?

name' OR 'a'='a

해당 SQL Query는 참으로 인식하여, 데이터베이스에 허가되지 않은 사용자가 접근할 수 있게 됩니다. 

간단한 입력값만으로도 데이터베이스의 정보를 조작하거나 열람, 심지어 삭제해버릴 수도 있는 무서운 공격이 됩니다.


따라서, SQL Query에 사용되는 외부 입력값의 경우에는 1) preparedStatement를 이용하여 DB에 컴파일된 쿼리문을 전달하는 방법을 사용하거나, 2) 외부입력값에 대해 필터링하는 구문을 앞단에서 작성해주어야 합니다.

- [preparedStatement를 사용하는 경우]

string userName = request.getParameter("username");

string query = "SELECT * FROM items where owner = '" + userName + "'";

PreparedStatement s_username = con.prepareStatement(query);

s_username.setString(1, userName);

ResultSet rs = s_username.executeQuery();


SQL Injection은 개발자의 개발습관에 따라 쉽게 막을 수 있는 공격이지만,

보안대책을 적절히 구현하지 못하였을 시에는 무서운 공격이 될 수도 있으므로 개발 시에 DB에 접근하는 Query문의 경우에 검증하는 로직을 필히 구현하시기 바랍니다.


WRITTEN BY
SiriusJ

,