| SQL Injection
웹 애플리케이션의 취약점을 이용하여 악의적인 SQL 코드를 삽입하는 것. 이를 통해서 데이터 베이스에 비정상적인 접근을 하는 것.
| SQL Injection 종류
- SQL Injection
- Blind SQL Injection
- Error based Injection
- Time based Injection
| SQL Injection 알아보기 (실습)
login_func.php (sql 쿼리 부분) - 로그인 로직
$sql = "select * from member_table where id='$userid' and pw='$userpw'";
$result = mysqli_query($db_conn, $sql);
$row = mysqli_fetch_array($result);
if($row){
session_regenerate_id(true);
$_SESSION['userid'] = $row['id'];
return true;
} else {
echo "<script>alert('로그인 실패')</script>";
return false;
}
위 소스코드는 로그인 시 로그인을 처리하는 코드입니다. 해당 로그인 로직을 가진 웹 페이지에서 SQL Injection 이 어떻게 이뤄지는 간단하게 알아보겠습니다.
▶️ 정상적인 로그인 과정

로그인 페이지에서 아이디와 비밀번호를 입력하면 쿼리문에 아이디 비밀번호에 입력 값들이 들어가게 됩니다. 즉, 다음과 같습니다.
"select * from member_table where id='아이디' and pw='비밀번호'"
만약 아이디가 mega이고, 비밀번호가 1234인 계정으로 로그인을 하면 다음과 같이 쿼리문이 이뤄집니다.
"select * from member_table where id='mega' and pw='1234'"
해당 계정으로 로그인을 하면 정상적으로 로그인이 되는 것을 볼 수 있습니다.

이번엔 로그인을 시도할 때 비정상적인 로그인 방법으로 시도 해보겠습니다.
▶️ 비정상적인 로그인 과정
❓만약 다음과 같이 아이디와 비밀번호를 입력했다면?
아이디 : mega’ or ‘1’=’1
비밀번호 : 1234

이렇게 비정상적인 방법으로 로그인을 시도해보겠습니다.

분명 원래 아이디가 mega인데 mega' or '1'='1 을 입력했더니 로그인이 된 상황입니다.
이런 식으로 임의의 쿼리를 삽입하여 DB에 비정상적인 접근을 하는 것을 SQL Injection 이라고 합니다.
이제 SQL Injection이 어떻게 가능한 건지에 대해서 알아보겠습니다.
❓SQL Injection이 어떻게 발생했는가?
로그인을 할 때, 사용자가 아이디와 비밀번호를 입력하면 그 정보를 가지고 DB 안에 있는 정보와 비교하여 일치하면 로그인, 불일치하면 로그인 실패로 이어지게 됩니다. 정상적인 로그인 시도와, 비정상적인 로그인 시도를 했을 때의 DB가 어떤 응답을 하고 있는지 살펴보면서 SQL Injection에 대해서 이해해 보겠습니다.
우선, DB에 있는 회원정보 테이블입니다.

아까 정상적인 로그인 시도할 때 아이디: mega, 비밀번호: 1234로 입력하고 로그인을 했었습니다. 이 때의 sql 쿼리를 DB에게 전송한다면 다음과 같은 결과를 반환 합니다.


결과 사진을 보면 sql 쿼리에 의해 아이디가 mega, 비밀번호가 1234인 계정을 가져오고 있는 모습입니다. 이번엔 잘못된 입력으로 로그인했을 때 어떤 결과값을 반환하는지 확인해 보겠습니다.


잘못된 아이디를 통해 비정상적인 로그인을 할 때와 정상적인 아이디를 통해 로그인을 시도할 때 DB는 같은 결과를 반환하고 있기에 로그인이 가능했던 것입니다. or '1'='1을 추가했는데 왜 같은 결과가 나오지?라고 생각해 볼 수 있는데 이는 비교 연산자의 우선순위 때문에 발생하게 됩니다.
id='mega' or '1'='1' and pw='1234' 즉, 빨간색으로 밑줄 되어있는 부분에서 연산이 먼저 일어나기 때문입니다.
'1'='1' and pw='1234'을 비교하면, and 조건은 비교하는 두 조건이 모두 참이 되어야 하며 1과 1은 같고 비밀번호(pw)도 1234가 맞기 때문에 true가 되게 됩니다. 그다음에 or을 연산하는데 or 연산자는 비교할 때 하나라도 참이라면 참이 되게 됩니다.
id='mega' or ('1'='1' and pw='1234') 이렇게 연산이 이뤄지게 되는데 id가 mega인 계정이 DB 내부에 있기 때문에 id='mega'는 참이 되게 됩니다. or 연산은 하나라도 참이면 참이기 때문에 where절이 참이되며 아이디가 mega인 계정을 DB는 반환하게 됩니다.
*** id='mega'(이미 여기가 참) or (or 뒤에 falsty한 값이 와도 or 앞에가 이미 참이므로 전체는 참) ***
다시 정리하면, id가 mega인 계정이 DB 내부에 있고(참), or 연산자로 인해 sql 쿼리의 where 절이 전체 적으로 참이 되어 id가 mega인 계정을 가져오게 되는 것입니다. 따라서 해당 로그인 인증 로직을 별다른 필터링없이 그대로 사용 중이라면 비밀번호를 아무거나 입력해도 로그인이 가능하게 됩니다. 아이디만 알고 있다면 sql 쿼리의 where 조건이 전부 참이 되도록 만들 수 있기 때문에 DB는 정상적으로 로그인했을 때와 같은 결과를 반환하게 됩니다.
정말로 아무 비밀번호를 입력했을 때 정상적으로 로그인 했을 때 와 같은 결과를 반환하는지 확인해보겠습니다.


결과를 확인해보면 DB가 정상적으로 로그인했을 때와 같은 결과를 반환하고 있다는 것을 알 수 있습니다.
이렇게 간단한 실습을 통해 SQL Injection에 대해서 알아봤는데 해당 글은 "SQL injection이 이런 거구나" 정도로 생각하시면 될 거 같습니다. 앞으로는 SQLInjection 종류에 대해 설명하고, 해당 SQL Injection 공격 기법이 어떤 식으로 사용되며 어떻게 DB 데이터를 추출까지 가게 되는지에 대해서 다뤄보겠습니다.