SQL Injection 에 대한 조치를 진행해본다.
예를 들면 검색 기능을 구현한다고 보면 간단하게 아래와 같은 쿼리를 작성하게 된다.
SELECT * FROM MYTABLE WHERE NAME LIKE '% ?';
만약 악의적인 사용자가 파라메터값으로 " '; SHOW DATABASES; -- " 이런 구문을 입력해 온다면
SELECT * FROM MYTABLE WHERE NAME LIKE '%'; SHOW DATABASE; -- ';
나의 쿼리 문은 종료되고, 뒤엔 데이터베이스를 출력할 수 있는 쿼리가 실행되게 된다.
만약 공격자가 테이블을 조회하는 쿼리를 넣었다면 테이블명까지 노출되고
심할경우 drop을 통해 테이블이 삭제되는 경우에 이를 수 있다.
이렇게 입력값을 이용해 내 쿼리를 조회를 방해하고, 악의적으로 데이터를 갈취할수 있는데
이에 방어하기 위한 조치를 진행해본다.
1. Codeigniter 에서 제공하는 xss_clean 사용!
xss_clean 은 크로스 사이트 스크립팅 공격을 방지하는 XSS 필터는 자바스크립트실행을 시도한다거나, 쿠키를 하이재킹한다거나, 다른 해괴망측한 짓거리들을 한다거나 하는 것을 막는 기술입니다. 만약 금지된 문자나 코드 등을 찾으면 데이터를 안전한 HTML 엔터티로 변환하여 표시합니다.
컨트롤러에서 검색값을 받을때 아래와 같이 필터링해준다.
$search["keyword"] = $this->security->xss_clean(@trim($search["keyword"]));
2. 정규식을 이용한 문자열 치환
파라메터값에서 쿼리 조회에 문제가 되는 텍스트가 있다면 "" 으로 변경해준다.
$string = @trim(preg_replace("/[#\&\+\-%@=\/\\\:;,\.'\"\^`~\_|\!\?\*$#<>()\[\]\{\}]/i", "", $string));
3. 한번 더 문자열 치환!
이건 경우에 따라 다를 것 같다. 나같은 경우 들어올 사용자 이름 조회에 사용하고있으므로
파라메터에 select 와 같은 문구가 들어올 경우가 적기에 이 또한 "" 처리했는데,
케바케로 용도에 맞게 사용해야할것같다. (str_ireplace = 이건 대소문자 구분없이 문자열 변경해준다. )
//iframe 제거
$string = preg_replace("!<iframe(.*?)<\/iframe>!is","",$string);
//script 제거
$string = preg_replace("!<script(.*?)<\/script>!is","",$string);
//meta 제거
$string = preg_replace("!<meta(.*?)>!is","",$string);
//style 태그 제거
$string = preg_replace("!<style(.*?)<\/style>!is","",$string);
// 기타 쿼리 조회에 사용되는 문구 제거
$string = @trim(str_ireplace("select", "", $string));
$string = @trim(str_ireplace("union", "", $string));
$string = @trim(str_ireplace("insert", "", $string));
$string = @trim(str_ireplace("update", "", $string));
$string = @trim(str_ireplace("delete", "", $string));
$string = @trim(str_ireplace("drop", "", $string));
$string = @trim(str_ireplace("from", "", $string));
4. 한번 더 걸러준다.. ( 절대 안되게 할꺼야! )ㅋㅋ
날짜와 같이 스크립트로 값을 입력해 가져오는 파라메터들에 방심하는 경우가 있다.
공격툴을 이용하면 파라메터 값을 마음대로 셋팅할 수 있으므로, 입력받는 파라메터라면 모두 처리해주어야한다.
$search["keyword"] = addslashes($search["keyword"]);
$search["sdate"] = addslashes($search["sdate"]);
$search["edate"] = addslashes($search["edate"]);