[라라벨] SQL Injection 공격 패턴 및 방어 방법
- 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'])