* 2022년 10월 19일 velog에 작성했던 게시글을 옮겨온 글입니다.
해커들이 사용하는 가장 흔한 웹 해킹 방법이 바로 SQL Injection이다. 조작된 SQL 쿼리문을 이용하여 데이터 베이스를 실행시키는 방식으로 이루어진다. SQL Injection 안에서도 여러가지 기법이 존재한다. 가장 흔하게 이용되는 기법은 논리적 오류
를 기반으로 한다.
1. 인증 우회
논리적 오류 기반 SQL Injection
SELECT * FROM users WHERE user_id = 1;
1번에 해당하는 유저가 없다면 해당 쿼리는 아무 결과도 출력하지 않는다.
SELECT * FROM users WHERE user_id = 1 OR 1=1;
그러나 OR 1=1
절을 붙여주면 모든 users 데이터가 조회된다. 심지어 1번 유저가 아닌 아무런 유저를 기입하여도 OR 조건절에 의해 실행된다. 1=1은 언제나 참이라는 논리적 오류를 기반으로 조건절이 참일 때 데이터를 불러올 수 있는 공격 기법이다.
UNION 명령어 기반 SQL Injection
SELECT * FROM carts WHERE product_id like '%'
UNION SELECT user_id, name FROM users;
UNION 명령어는 두 쿼리문을 실행시킨 결과를 하나의 테이블로 보여주는 함수이다. 조회 결과시 두 테이블의 컬럼수, 데이터 타입이 같아야 한다. 만약 컬럼 수가 모자라거나 많다면 null등을 이용하여 조회할 수도 있다. 위와 같이 장바구니를 조회하는 쿼리문에 UNION 명령어를 이용하여 유저를 조회하는 쿼리문을 실행시키면 장바구니, 유저 데이터 전체가 조회된다.
password!; DELETE FROM users WHERE user_id = 1;
이렇게 알아낸 아이디와 비밀번호 등을 이용하여 로그인을 할 수 있다. 비밀번호를 입력할 때 동시에 다른 쿼리를 입력하면 함께 실행이 되어 데이터 베이스에 영향을 줄 수도 있다.
2. 데이터 노출
일부러 에러를 내서 데이터 구조를 파악하는 SQL Injection 기법이다. GET 방식으로 동작하는 URL 쿼리 스트링을 추가하여 에러를 발생시키면 어떤 데이터들이 필요한지 에러를 반환한다. 이때 이 에러를 보고 데이터 베이스 구조를 유추할 수 있다.
예방하기 위해서
- 에러 메세지 노출하지 않기
해커도 SQL Injection을 하려면 데이터베이스의 정보가 필요하다. 이때 일부러 SQL 에러를 내서 테이블, 컬럼 등의 정보를 알아내지 못하도록 데이터 베이스 에러시에 따로 에러 메세지를 정하여 반환하거나 일반 사용자는 view로만 접근하여 에러를 볼 수 없도록 만들어야 한다. - Prepared Statement를 사용하기
쿼리가 DBMS에서 어떻게 실행되는지 알아야 이해할 수 있는 예방법이다. 일반적인 방법은 Statement 방식으로parse, bind, execute, fetch
과정을 거쳐 결과를 출력한다. 이중 parse는 1. 문법 검사, 2. 의미 검사, 3. 권한 검사, 4. 실행 계획을 세우는 과정으로 아래와 같은 parsing tree를 만든다.
일반적인 Statement 방식은 매번 네단계 과정을 수행하지만 Prepared Statement의 경우 parse과정은 최초 한번 수행하고 이후에는 하지 않는다. 최초의 파싱 과정에서 생성된 트리를 반복적으로 사용하기 위해서 자주 변경되는 부분을 변수로 선언하고 그 때마다 다른 값을 바인딩하여 사용한다.
바인딩 값은 SQL 문법이 아니므로 SQL Injection이 통하지 않아 예방할 수 있게 된다.
// 바인드 변수 설정 ⭕️
INSERT INTO users(user_id, name) VALUES(?, ?);
// 바인드 변수 설정 ❌
INSERT INTO users(user_id, name) VALUES("+user_id+", "+name+");
* 아래의 자료들을 참고하였습니다.
'DataBase' 카테고리의 다른 글
Redis Sentinel 이해하기 (0) | 2023.03.02 |
---|---|
Mysql JSON 형태로 조회하기 (2) | 2022.12.31 |
데이터를 운반하는 트럭 Packet (0) | 2022.12.31 |
콜백 지옥에 이은 join 지옥 (0) | 2022.12.14 |
DB와 DBMS의 차이점 (0) | 2022.12.14 |
댓글