본문 바로가기

Dev.Basic/데이터베이스

SQL Injection이란 무엇인가

[보안] SQL Injection

SQL Injection 이란 Web hacking 기법 중 하나이다. 웹 애플리케이션의 뒷단에 있는 Database에 질의(쿼리를 보내는 것)하는 과정 사이에 일반적인 값 외에 악의적인 의도를 갖는 구문을 삽입하여 공격자가 원하는 SQL 쿼리문을 실행하는 기법이다. 주로 사용자가 입력한 데이터를 제대로 필터링, 이스케이핑 하지 못했을 경우에 발생한다. 요즘의 거의 모든 데이터베이스 엔진은 유저 입력이 의도치 않은 동작을 하는 것을 방지하기 위해 escape 함수와 prepared statement를 제공한다.

SQL Injection 공격의 종류에는 크게 세 가지 유형이 있다.
인증 우회 (AB : Auth Bypass)
데이터 노출 (DD : Data Disclosure)
원격명령 실행 (RCE : Remote Command Excute)

1) 인증 우회
보통 아이디와 패스워드를 입력하는 로그인 페이지를 타켓으로 행해지는 공격이다. SQL 쿼리문의 true/false의 논리적 연산 오류를 이용하여 로그인 인증 쿼리문이 무조건 true의 결과값이 나오게 하여 인증을 무력화 시키는 원리이다.
ex) ID와 password에 or 1=1-- 입력

2) 데이터 노출
타겟 시스템의 주요 데이터 절취를 목적으로 하는 방식이다. Error based, Union based, Blind based, Time based 방식이 있다. 시스템의 에러는 개발자에게 버그를 수정하는 면에서 많은 도움을 주지만 역으로 에러를 이용할 수 있다. 악의적인 구문을 삽입하여 에러를 유발시키는 것이다.
해커는 GET 방식으로 동작하는 url에 추가적인 `query string`을 추가하여 에러를 발생시킬 수 있다. 이에 해당하는 오류가 나타난다면 그것을 가지고 데이터베이스의 구조를 유추할 수 있다. 그렇기 때문에 오류 페이지 또는 오류 메시지가 노출되어서는 안된다.

방어 방법
1. 대부분의 SQL Injection의 경우 값을 입력받을 때 특수문자 여부를 검사하여 방어한다.
아이디와 패스워드를 입력받는 입력에 특수문자가 포함되어 있는지 검증 로직을 추가하여 특수문자가 입력된 경우 해당 요청을 막아낼 수 있다.

2. SQL 서버에 오류가 발생했을시 해당하는 에러 메시지를 표시해선 안된다.
테이블에서는 모든 정보를 가지고 있지만 View를 사용하면 테이블의 일부만 보일 수 있고 접근 권한을 다르게 할 수도 있다. 원본의 테이블에는 접근 권한을 높이고 일반 사용자는 view로만 접근하게 되면 원본 테이블이 공격에 의해 노출되는 정도를 줄일 수 있다.

3. Statement대신 preparestatement를 사용하자.
mysql의 Preparedstatement 구문을 사용하면 특수문자를 자동으로 escaping 해준다. 클라이언트 측 자바스크립트로 폼 입력값을 우선 검증하자. 하지만 자바스크립트는 공격자가 꺼버리면 그만이기 때문에 서버 측에서 입력값을 한 번 더 필터한다.

4. hash function을 사용하자.
사용자의 입력값을 데이터베이스에 그대로 저장하고 사용하지 말아야 한다. 특히 패스워드의 경우가 그렇다. 무조건 SHA-256 이상의 보안성을 갖는 해시함수로 해싱한 뒤 저장해야 한다.


end