우선 SQL Injection이 무엇인지와
이로 인한 사례, 예시들을 보고 이를 어떻게 하면 막을 수 있는지 알아보기로 하자.
SQL Injection이란?
응용 프로그램 보안 상의 허점을 의도적으로 이용해, 악의적인 SQL문을 실행되게 함으로써 데이터베이스를 비정상적으로 조작하는 Code Injection 공격 방법이다. 대부분 클라이언트가 입력한 데이터를 제대로 필터링하지 못하는 경우에 발생하며 공격의 난이도에 비해 피해가 상당하기 때문에 보안 위협 1순위로 불릴 만큼 중요한 기법이다. Injection 공격은 OWASP Top 10 중 제일 상위 1위에 속해 있어 간과할 수 없다.
OWASP는 오픈소스 웹 애플리케이션 보안 프로젝트로 주로 웹에 관한 정보노출, 악성 파일 및 스크립트, 보안 취약점 등을 연구하는데 10대 웹 애플리케이션의 취약점 Top 10을 발표했다. 여기에 Injection 공격이 들어가 있는 것이다.
SQL Injection의 피해사례로는 과거의 '소니, 네이트, 넥슨' 의 정보유출 및 해킹 사건이 있으며 제일 최근에 알려진 바에 의하면 '여기 어때' 또한 SQL Injection으로 많은 피해를 보았다.
SQL Injection공격은 왜 발생하는 것일까?
이를 근본적으로 생각해보았는데 통상적으로 웹 애플리케이션은 클라이언트의 행동(클릭, 입력 등)에 따라 DB에 있는 데이터를 서로 다르게 표시하게 된다. 이를 위해 Query는 User가 입력한 데이터를 포함하여 Dynamic 하게 변하므로 개발자가 의도하지 않은 정보를 열람할 수 있게 되어 발생한다고 한다.
SQL Injection 피해가 생기는 시나리오를 순차적으로 정리해보자면
예를 들어 각 클라이언트들의 인적정보를 조회 할 수 있는 시스템이 존재하는데 통상적으로 SQL 로직은 ABC라는 클라이언트가 있을 때 인적정보라는 버튼을 클릭하게 되면 ABC라는 이름이 웹 서버에 들어가게 되고 DB에 입력한 값이 있는지 유무를 확인 후 있다면 인적정보를 출력해주는 식이다. 여기에서 XYZ라는 클라이언트는 위의 경우를 보자면 자신의 XYZ를 조회해야 되는데 SQL 문을 변경하여 ABC(타인)의 인적정보를 조회한다는 것이다.
예를 들어 ABC의 인적정보 버튼 클릭 시 해당 URL이 https://userinfo.com/mysearch?=ABC 가 된다고 보면 XYZ의 경우에도 https://userinfo.com/mysearch?=XYZ 가 되는데 해커 입장에서의 XYZ는 뒤의 자신의 XYZ를 ABC로 바꾸어야 하는 것이 맞는데 단순히 변경하는 것만으로는 현재 로그인된 자신과는 다르기에 서버에서는 인정하지 않는다. 그렇기에 특정 Query문을 넣어주는데 너무나 간결한 코드이다.
아래 코드를 보자면 'OR' 1 '=' 1 를 끝에 추가하여 1과 1이 같으면 True이고, OR은 어느 것 중 하나라도 True 일시 True 이기 때문에 이 Query문으로 로그인을 할 수 있게 된다.
1
2
3
|
SELECT * FROM CLIENT WHERE NAME='ABC' AND PASSWORD='123123'
SELECT * FROM CLIENT WHERE NAME='ABC' AND PASSWORD='OR'1'='1
|
cs |
이를 Error based SQL Injection이라고 하며 논리적 에러를 이용한 SQL Injection이다.
정말 매우 간단한 Query문이지만 정말 위험한 것이다.
다른 Injection 공격을 알아보자.
Union based SQL Injection (Union 명령어를 이용한 SQL Injection)
1
2
3
4
5
6
7
8
|
// 테이블에서 게시글을 검색하는 Query문
SELECT * FROM infoTable WHERE title LIKE '%INPUT%' OR contents '%INPUT%'
// 사용자의 id와 password를 요청하는 Query문
UNION SELECT null,id,password FROM Client--
// Injection 성공시 사용자의 게시글과 id,password가 보여지게됨
SELECT * FROM infoTable WHERE title LIKE '%' UNION SELECT null, id, password FROM Client
|
cs |
SQL에서 Union 키워드는 두 개의 Query문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드로 정상적인 Query문에 Union 키워드를 사용하여 인젝션에 성공하면, 원하는 Query문을 실행할 수 있게 된다. Union Injection을 성공하기 위해서는 두 가지의 조건이 있는데 먼저 Union 하는 두 테이블의 칼럼 수가 같아야 하고, 다음으로는 데이터 형이 같아야 한다는 것이다.
이러한 SQL Injection을 막기 위한 방법에는 어떠한 것들이 있을까?
입력 값에 대한 검증
SQL Injection 에서 사용되는 기법과 키워드는 앞서 두 가지 정도의 경우만 이야기 했지만 엄청나게 많다고 한다. 그렇기에 사용자의 입력 값에 대한 검증이 필요하다. 물론 서버에서도 식별된 것(whitelist)들을 기반으로 검증해야 할 것이다.
Prepared Statement 구문사용
Prepared Statement란 DB에서 동일하거나 비슷한 DB문을 높은 효율성으로 반복적으로 실행하기 위해 사용되는 기능으로 Prepared Statement 구문을 사용하게 되면, 사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에DBMS가 미리 컴파일 하여 실행하지 않고 대기한다. 그 후 사용자의 입력 값을 문자열로 인식하게 하여 공격Query가 들어간다고 하더라도, 사용자의 입력은 이미 의미 없는 단순 문자열 이기 때문에 전체 Query문도 공격자의 의도대로 작동하지 않는다고 한다.
Error Message 노출 금지
공격자가 SQL Injection을 수행하기 위해서는 DB의 정보(테이블명, 컬럼명 등)가 필요하다. DB 에러 발생 시 따로 처리를 해주지 않았다면, 에러가 발생한 Query과 함께 에러에 관한 내용을 반환하게 되는데 여기서 테이블명 및 컬럼명 그리고 Query문이 노출이 될 수 있기 때문에, DB에 대한 오류발생 시 사용자에게 보여줄 수 있는 페이지를 제작하거나 또는 메시지박스를 띄울 수 있도록 해야한다.
웹 방화벽 사용
웹 공격 방어에 특화되어있는 웹 방화벽을 사용하는 것도 하나의 방법이다. 웹 방화벽은 소프트웨어 형, 하드웨어 형, 프록시 형 이렇게 세가지 종류로 나눌 수 있는데 소프트웨어 형은 서버 내에 직접 설치하는 방법이고, 하드웨어 형은 네트워크 상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 것이며 마지막으로 프록시 형은 DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법이라고 한다.
이 것 말고도 여러가지 대응방안들이 존재한다고 한다.
출처 및 참고문헌
https://m.blog.naver.com/lstarrlodyl/221837243294
https://noirstar.tistory.com/264
'TIL' 카테고리의 다른 글
6/3[TIL] Database Indexing이란 무엇이며 왜 하는가요? (0) | 2021.06.03 |
---|---|
6/2[TIL] Transaction 이란 무엇이며 언제 사용하는가 (0) | 2021.06.02 |
5/30[TIL] 사용자의 비밀번호는 어떻게 저장하나요? (0) | 2021.05.30 |
4/26[TIL] 행동에는 결과가 따른다(5) (0) | 2021.04.26 |
4/19[TIL] 행동에는 결과가 따른다(4) (0) | 2021.04.19 |