- SQL 인젝션(주입, inject) Attack 해킹 공격 기법과 대응법


//-------------------------------------
* 기본 패턴
    - 입력값을 끊어서 공격자의 쿼리를 실행하고 주석( # , -- ) 처리


//-------------------------------------
* 검색 조건 무효화

    - 숫자 형식 :   1 OR 1 # 
SELECT * FROM Users WHERE UserId = 1 OR 1 # password = 'qwe' ;


    - 문자 형식 :   admin' OR 1 # 
        - 다른 유저로 로그인 가능
SELECT * FROM users WHERE name='admin' OR 1 # ' and age = 2 ;


//-------------------------------------
* 공격자 쿼리 실행
    ' ; DROP TABLE tbl1 ; # 
SELECT * FROM users WHERE name = 'a';DROP TABLE tbl1; #  and 't' = 't';


//-------------------------------------
* UNION 사용
    - 다른 회원 으로 로그인
SELECT * FROM users WHERE id = '10' and password = 'pass' UNION select 'admin', '1';#
        -

    - DB 내용 알아냄
SELECT * FROM users WHERE  col1= 'val' UNION select userid, password from users;#


//-------------------------------------
* 백슬래시 이용

username: \
password: or 1 #

$query = "SELECT * FROM users WHERE  username='" . $username . "' and password='" . $password . "'";

    - 결과
SELECT * FROM users WHERE  username='\' or password=' or 1 # ';
        - 백슬래시로 인해 따옴표가 내부 문자열이 되어 다음 조건까지 잠식
            - 결과 적으로 username='\' or password=' 가 한 조건이 됨


//-----------------------------------------------------------------------------

//-------------------------------------
* 방어법 : 

- 숫자 형식 : 숫자형식으로 강제 형변환  
    ex) $col = (int) $val;


- 문자열 형식 :  따옴표, 백슬래시를 이스케이핑
    php : addslashes() 사용
    - 주의!  mysql에 저장시 따옴표 그대로 저장됨
        - 다시 로드시 공격문자열이 그대로 불러짐




//-----------------------------------------------------------------------------
php, 라라벨

where() - 안전

    - PDO::prepare() 가 적용되어 위험 문자열이 이스케이핑 됨



//-------------------------------------
* php 라라벨 , 안전하지 않은 쿼리 실행 함수

 

*Raw() 계열 함수
    - whereRaw() , selectRaw() , fromRaw() , ...

DB::select(); // 쿼리 결과 DB 자료 리턴

DB::statement(); // BOOL 값 리턴, insert 등에 사용
DB::unprepared();

DB::insert();
DB::update();
DB::delete();


    - *Raw() 계열 함수도 안전하게 실행하는 방법
https://laravel.com/api/5.8/Illuminate/Database/Query/Builder.html

        - 인자 사용
$results = DB::select('select * from users where id = ? and name = ?', [1, 'a']);

$results = DB::select('select * from users where id = :id and name = :name', ['id' => 1, 'name' => 'a']);

    ->whereRaw('col1 = ?', ['a'])


반응형
Posted by codens