[SQL Injection] 시큐어 코딩 : 블랙리스트 필터링

 시큐어 코딩 


SQL 인젝션 초기 방안중에 가장 효율적인 방법은 근본 원인에 해당하는 소스 코드에서 취약점을 제거하는 것입니다 . 

코드 레벨에서 대응이 가능한 방법은 데이터 유형을 검사하는 방법과 키워드 필터링 그리고 준비된 상태를 적용하는 방법이 있습니다 .
 

구분 

대응방안

코드레벨

화이트/블랙리스트 키워드 필터링 

 

데이터 유형 검사

 

프리페어드 스테이먼트 적용 



코드 레벨 대응 방안에 대해서 간략하게 요약하면 다음과 같습니다 . 


키워드 필터링 : 허용할 문자열을 목록화 하여 필터링하는 화이트 리스트와 악의적인 키워드만 필터링 하는 블랙리스트 필터링이 있습니다 . 



데이터 유형 검사 : 파라미터의 데이터 타입이 무엇인지 확인한 다음 해당타입의 데이터 인지 검증하는 방법입니다 .  
특수 문자등 이스케이프 처리 또는 정규식으로 입력 가능한 문자열 범위를 검사하는 방법이 있습니다 . 



프리페어드 스테이먼트 : 준비된 상태라는 의미로 DB 에서 해석이 가능한 상태로 미리 컴파일한 다음에 입력한 값을 대입하는 방식으로 쿼리 구문 조작이 성립되지 않는 가장 안전한 방식입니다 . 


필터링 기법 

필터링 기법은 입력 값 검증으로도 불리며, 운영중인 서버에서 소스코드 수정을 최소화 하면서 취약점을 제거할 수 있는 유용한 방법중 하나입니다 . 

차단리스트으의 악의적인 키워드만 차단하는 블랙리스트 필터링 기법과 허용된 리스트외에 모든 키워드를 차단하는 화이트 리스트 필터링 기법이 있습니다 . 




















블랙리스트 필터링

블랙리스트 필터링은 악의적인 키워드가 포함되어 있는지 검사 후 차단합니다 . 


SQL 인젝션 주요 필터링 키워드 
', ", --, ;, /*, */, union, select, insert, drop, update, from, where, join, substr, tabs, cols, user_tables, user_table_columns, substring, sysobject ....



과도한 차단은 보안성 강화 측면에서 효과적이지만 서비스 장애나 사용자의 불편을 초래합니다 . 
소스코드로 실습을 진행해보도록 하겠습니다 .
 

소스코드
기존 empinfo_id.php파일에 다음을 추가합니다 .


$count = 0;
$items = array("'", "\"", " --", "#" , ";","/*" , "*/" , "union", "select", "insert ",
"drop" , "update", "from", "where", "join", "substr" , "tab" , "cols" , "user_tables" ,
"user_table_columns", "substring" , "information_schema" , "sysobjects", "order");

$_empid  = $_GET['empid'];
str_replace($items, '',$_empid,$count);

if($count>0){
        $_empid = 0;
}



완성코드 
<?php

if (!$link = mysql_connect('localhost', 'root', 'root')) {
    echo 'Could not connect to mysql';
    exit;
}

if (!mysql_select_db('northwind', $link)) {
    echo 'Could not select database';
    exit;
}
$count = 0;
$items = array("'", "\"", " --", "#" , ";","/*" , "*/" , "union", "select", "insert ",
"drop" , "update", "from", "where", "join", "substr" , "tab" , "cols" , "user_tables" ,
"user_table_columns", "substring" , "information_schema" , "sysobjects", "order");

$_empid  = $_GET['empid'];
str_replace($items, '',$_empid,$count);

if($count>0){
        $_empid = 0;
}
$sql    = 'SELECT * FROM Employees WHERE EmployeeID=' . $_empid;
$result = mysql_query($sql, $link);

if (!$result) {
    echo "DB Error, could not query the database\n";
    echo 'MySQL Error: ' . mysql_error();
    exit;
}

print "<table border=1 cellpadding=5 cellspacing=0>\n";
print "\t<tr>\n\t\t<td>Employee ID</td><td>First Name</td><td>Title</td><td>Hire Date</td>\n\t</tr>";

while ($row = mysql_fetch_assoc($result)) {
    print "\t<tr>\n\t\t<td>" . $row['EmployeeID'] . "</td><td>" . $row['FirstName'] . "</td><td>" . $row['Title'] . "</td><td>" . $row['HireDate'] . "</td>\n\t</tr>\n";
}
print "</table>\n";

mysql_free_result($result);
?>



필터링이 추가된 예시에 SQL 인젝션 공격을 수행하면 공격키워드는 다음과 같이 필터링 되어 취약점이 발생하지 않습니다 . 














블랙리스트 필터링은 서비스에서 사용하는 키워드인지 주의가 필요하며 또한 필터링 리스트에 누락된 키워드가 있을 경우 우회가 가능하다는 문제가 발생할 수 있음을 늘 고려해야합니다.

댓글