Web Hacking/Information

SQL INJECTION 예방책 - prepared statement

프레딕 2023. 10. 28. 22:00
728x90

sql injection이 발생하는 주 이유는 사용자가 입력한 값을 쿼리에 그대로 대입시키기 때문이다.

그 예방책으로 쿼리문을 파라미터 쿼리로 변경하는 방법이 있다.

다음은 DVWA에서 가져온 예제 코드이다.

<?php

if( isset( $_GET[ 'Submit' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $id = $_GET[ 'id' ];

    // Was a number entered?
    if(is_numeric( $id )) {
        // Check the database
        $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
        $data->bindParam( ':id', $id, PDO::PARAM_INT );
        $data->execute();
        $row = $data->fetch();

        // Make sure only 1 result is returned
        if( $data->rowCount() == 1 ) {
            // Get values
            $first = $row[ 'first_name' ];
            $last  = $row[ 'last_name' ];

            // Feedback for end user
            echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
        }
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?>

 

if(is_numeric($id)) 괄호 안에 내용을 보면 prepare(), bindParam(), execute()를 각각 호출해 쿼리문을 실행하고 있다.

특히 prepare함수에 쿼리문이 담겨있는데 이를  prepared statement라고 한다. 

쿼리문을 prepare함수로 준비상태로 대기시켜 놨다가 bindparam으로 id값을 바인딩한다. 그 후 execute함수로 실행시키는데 준비상태로 들어간 쿼리는 실행 전에 권한이 부여되지 않다가 실행 시킬때 권한이 확인되는 특징이 있다.

 

여기선 짧게 정리했지만 다른 언어들에도 prepared statement를 구현하는 함수가 각각 있으므로 더 찾아볼 필요성이 있다.

728x90
반응형