지식나눔

공유하기

SQL 인젝션 대비

SQL 인젝션

프로그램 부 에서 DB 로 질의 하는 QUERY문 을 공격자가 임의로 변조하여 허가되지 않은 자료나 관리자/회원 권한을 획득할 수 있는 공격입니다.

공격 예제

<?php
// 회원 로그인 시 아이디와 패스워드가 맞는 회원정보를 찾는 쿼리
$query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($query);
// $_POST['password'] 을 체크하지 않은 경우 아래와 같이 공격자의 입력이 있을 수 있음
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";
// 쿼리출력
echo $query;
// DB로 전송되는 쿼리를 출력해 보면 아래와 같다.
// SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''
// 이 쿼리는 ''='' 조건이 or 로 조합되어 있어 무조건 참이며 DB는 aidan 이라는 회원의 레코드셋을 반환하게 된다.
?>
 

해결책

가변적으로 대입되는 쿼리문의 모든 요소를 mysql_real_escape_string() 이라는 함수를 이용하여 특수 문자를 escape 시켜야 합니다. 아래의 예제는 php.net 에서 권장하는 가장 좋은 방법의 예 입니다.
 
<?php
if (isset($_POST['product_name']) && isset($_POST['product_description']) && isset($_POST['user_id'])) {
    // 접속
    $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password');
    if(!is_resource($link)) {
        echo "서버 접속 실패n";
        // ... 오류를 적절히 기록
    } else {
        // ON일 경우 magic_quotes_gpc/magic_quotes_sybase 효과 제거
        if(get_magic_quotes_gpc()) {
            $product_name        = stripslashes($_POST['product_name']);
            $product_description = stripslashes($_POST['product_description']);
        } else {
            $product_name        = $_POST['product_name'];
            $product_description = $_POST['product_description'];
        }
        // 안전한 질의 만들기
        $query = sprintf("INSERT INTO products (`name`, `description`, `user_id`) VALUES ('%s', '%s', %d)",
                    mysql_real_escape_string($product_name, $link),
                    mysql_real_escape_string($product_description, $link),
                    $_POST['user_id']);
        mysql_query($query, $link);
        if (mysql_affected_rows($link) > 0) {
            echo "Product insertedn";
        }
    }
} else {
    echo "Fill the form propertyn";
}
?>
 
보통, 기본적으로 Magic Quotes 설정에 의해 막아지고는 있으나 6.0 이상부터는 이 기능이 제거되니 의존하지 않기를 권장하고 있습니다.
 
에이빌더에서는 library_lite.class.php 내의 함수 sql_inj_get_safe_value, sql_inj_get_query 로 조치하고 있으며 지속으로 패턴을 추가하고 있습니다.
공유하기
등록자

이주한

등록일
2009-09-29 07:36
조회
19,348