# SQL Injection

> SQL 인젝션은 악의적인 사용자가 **보안상의 취약점**을 이용하여,\
> 조작된 쿼리문을 DB에 그대로 전달하여 비정상적 명령을 실행시키는 공격 기법

<br>

## 공격 목적

1. 정보 유출
2. 저장된 데이터 유출 및 조작
3. 원격 코드 실행
   * 일부 데이터베이스의 경우 확장 프로시저를 이용하여 원격으로 시스템 명령의 실행 가능
   * 시스템 명령의 실행은 원격 자원 접근 및 데이터 유출, 삭제 가능
4. 인증 우회
   * 공격의 대표적인 경우는 로그인 폼에서 발생
   * 이때 상위 권한을 가진 사용자의 권한으로 인증 절차를 우회하여 로그인

<br>

## 발생 조건

1. 사용자 입력값의 신뢰성 부족
   * 사용자로부터 입력 받은 값(폼 데이터, URL 파라미터)을 적절히 검증 또는 이스케이프하지 않은 경우 발생
2. 동적 SQL 쿼리 생성
   * 동적으로 SQL 쿼리를 생성하고 사용하는 경우, 사용자 입력 값이 직접 쿼리에 삽입되면서 발생
3. 실행 권한 문제
   * 사용자가 실행할 수 없는 쿼리를 실행하려고 하는 경우, 이를 불허하지 않고 실행하게 되면 발생

<br>

## 공격 종류 및 방법

| 구분           | 예시                                  |
| ------------ | ----------------------------------- |
| Classic SQLi | Error-based SQLi, Union-based SQLi  |
| Blind SQLi   | Boolean-based SQLi, Time-based SQLi |

<br>

### Error based SQL Injection

> **논리적 에러**를 이용한 SQL 인젝션은 대중적인 공격 기법

<br>

**예시) 로그인 상황**

<br>

```sql
SELECT * FROM users WHERE username = '입력된_사용자명' AND password = '입력된_비밀번호';
```

만약 사용자가 아래와 같이 입력한다면

```sql
'' OR '1'='1'; --
```

SQL은 최종적으로 다음과 같이 변한다.

```sql
SELECT * FROM users WHERE username = '' OR '1'='1'; --' AND password = '입력된_비밀번호';
```

* `'1'='1'` 구문 이용
  * WHERE 절을 모두 참으로 만듦
  * `--`를 넣어줌으로써 뒤의 구문을 모두 주석처리
* 위 쿼리문 실행 시
  * Users 테이블에 있는 모든 정보를 조회
  * 가장 먼저 만들어진 계정으로 로그인에 성공
    * 보통은 관리자 계정을 제일 처음 만듦
      * 관리자 계정 탈취로, 관리자 권한을 통해 또 다른 2차 피해 발생 가능

\ <br>

### Union based SQL Injection

**UNION** : 두 개의 쿼리문에 대한 결과를 통합하여 하나의 테이블로 보여주는 키워드

**Union 인젝션 성공을 위한 조건**

1. Union 하는 두 테이블의 `컬럼 수`가 같아야 함
2. Union 하는 두 테이블의 `데이터 형`이 같아야 함

\ <br>

**예시) 사용자의 아이디와 패스워드 확인**

<br>

```sql
SELECT username, password FROM users WHERE id = '$id';
```

이때 '$id'에 아래와 같은 값을 입력한다면,

```sql
$id: 1 UNION SELECT null, table_name FROM information_schema.tables --
```

최종 쿼리는 아래와 같다.

```sql
SELECT username, password FROM users WHERE id = '1' UNION SELECT null, table_name FROM information_schema.tables --';
```

`UNION SELECT null, table_name FROM information_schema.tables` 부분은 사용자 테이블 대신 `information_schema`에서 테이블 이름을 가져오는 부분이다.

이 경우 공격자는 **추가로 가져온 테이블의 정보**를 이용하여 데이터베이스를 조작할 수 있다.

\ <br>

### Boolean based SQL Injection

> SQL 쿼리의 **참/거짓 기반**으로 공격자가 DB 정보를 추출하는 기법

<br>

**예시) 아이디가 '1'인 사용자의 비밀번호 길이 확인**

<br>

```sql
SELECT username, password FROM users WHERE id = '$id';
```

공격자가 아이디가 '1'인 사용자의 비밀번호 길이를 확인하는 쿼리를 실행하려고 한다.

```sql
$id: 1' AND LENGTH(password) > 10 --
```

이 입력을 SQL 쿼리에 삽입하면 아래와 같이 된다.

```sql
SELECT username, password FROM users WHERE id = '1' AND LENGTH(password) > 10 --';
```

해당 값의 결과가 웹 페이지에 반영되면 공격자는 비밀번호의 길이를 추출할 수 있다. 이런 과정을 반복하여 결과들을 조합한다면 원하는 정보를 얻을 수 있다.

\ <br>

### Time based SQL Injection

> **DB 서버의 응답 시간**을 기반으로 공격자가 데이터베이스 정보를 추출하는 기법

<br>

**동작 방식**

* DB 쿼리에 시간을 지연시키는 함수를 삽입하여, 결과를 확인하는 방식으로 작동
* 공격자는 쿼리의 참/거짓 여부에 따라 서버 응답 시간의 변화 관찰
  * 이를 통해 DB 정보를 유추하거나 추출

<br>

**예시) 아이디와 비밀번호 조회 코드**

<br>

```sql
SELECT username, password FROM users WHERE id = '$id';
```

공격자가 아이디가 '1'인 사용자 비빌번호의 첫 번째 글짜가 'a'인지 확인하고자 한다.

```sql
$id: 1' AND SUBSTRING(password, 1, 1) = 'a' AND SLEEP(5) --
```

이 입력을 SQL 쿼리에 삽입하면 결과적으로 아래와 같이 변한다.

```sql
SELECT username, password FROM users WHERE id = '1' AND SUBSTRING(password, 1, 1) = 'a' AND SLEEP(5) --';
```

여기서 `SUBSTRING(password, 1, 1) = 'a'` 조건이 만족될 때까지 서버는 5초 동안 응답을 보류하게 되고, 공격자는 이를 이용하여 패스워드의 첫 글자를 추측할 수 있다.

\ <br>

## 대응 방안

1. **화이트리스트 기반 검증**
   * 허용되는 값의 목록을 작성하고, 입력 값이 이 목록에 속하는지 확인하는 방식.
   * 허용되지 않은 문자나 특수 문자를 입력으로 거부함으로써 공격을 방지할 수 있음.
2. **Prepared Statement 사용**
   * 입력 값을 문자열로 취급하고 데이터베이스의 파라미터로 처리하는 방법.
   * 이는 SQL 쿼리를 미리 컴파일하여 실행하는 방식으로, 공격자가 의도한 쿼리를 실행할 수 없게 한다.
3. **에러 메시지 최소화**
   * 에러 메시지에는 민감한 정보가 포함될 수 있다.
     * ex) 데이터베이스 버전정보
   * 따라서 실제 사용자에게는 유용한 정보만을 포함하도록 에러 메시지를 최소화해야 함.
   * 이로서 공격자가 데이터베이스 구조를 파악하기 어렵게 만듭니다.
4. **웹 방화벽 사용**
   * 웹 방화벽은 웹 애플리케이션의 트래픽을 감시하고, 악의적인 행위로부터 보호하는 역할.
   * SQL Injection과 같은 웹 공격을 탐지하고 차단할 수 있다.
5. **입력 값의 정규화**
   * 입력 값이 예상과 다른 형식이면 거부하도록 정규화를 수행.
   * 예를 들어, 숫자를 기대하는 필드에 문자열이 입력되는 경우를 방지할 수 있다.
6. **최소 권한 원칙**
   * 데이터베이스 계정에는 최소한의 권한만 부여하는 것이 중요.
   * 애플리케이션이 필요로 하는 최소한의 권한만 부여함으로써 특정 공격에 대한 영향을 최소화.
7. **보안 업데이트**
   * 데이터베이스 시스템, 웹 서버, 프레임워크 등을 최신으로 유지하고 보안 업데이트를 적용하는 것이 중요.
   * 새로운 취약점에 대한 패치가 제공되면 빠르게 업데이트해야 한다.

이러한 방법들을 종합적으로 사용함으로써 SQL 인젝션에 안전한 웹 애플리케이션을 구축할 수 있다.

\ <br>

## 블랙리스트 vs 화이트리스트

> 시스템에 접근해도 되는 사용자와 접근하면 안 되는 사용자를 구분하기 위해 사용되는 목록\
> 이때 대상은 사람뿐 만이 아닌 특정 IP를 가진 PC, 실행 파일, 프로세스, 웹 사이트 등이 되기도 함

### 화이트리스트

* 개념
  * 엑세스 허용 목록
  * 기본적으로 모든 접근을 막아놓고 접근 허용 대상만 따로 등록하는 방식
  * 조직 내에서 신뢰할 수 있는 실행 파일, 응용 프로그램, 웹 사이트만 실행 가능하도록 허용
* 장점
  * 좀 더 엄격한 보안체계 구축 가능
* 단점
  * 보안 담당자에게 더 많은 업무 주어짐
    * 특정 업무 시스템의 접근 권한을 통제하면, 자신도 등록해달라는 요청 발생

<br>

### 블랙리스트

* 개념
  * 엑세스 거부 목록
  * 기본적으로 접근을 모두 허용하돼 접근하지 못하는 예외를 두는 방식
* 특징
  * 컴퓨터 보안에서 가장 오래된 알고리즘 중 하나
  * 방화벽이나 백신 소프트웨어 등에 자주 사용
* 장점
  * 쉽고 빠른 보안 조치 가능
  * 담당자의 노동이 적게 들어감
* 단점
  * 거부하지 않은 출처로부터 엑세스가 있는 경우 막기 어려움

<br>

#### ref

[SQL Injection 이란? (SQL 삽입 공격)](https://noirstar.tistory.com/264)\
[SQL Injection and How to Prevent It?](https://www.baeldung.com/sql-injection)\
[\[웹해킹\] SQL Injection 총정리](https://gomguk.tistory.com/118)
