Self-Improvement

SQLi 대응방안 (Magic_quotes_gpc, 프리페어드 스테이트먼트, 키워드 필터링, 데이터 유형 검사 등) 본문

SQLi

SQLi 대응방안 (Magic_quotes_gpc, 프리페어드 스테이트먼트, 키워드 필터링, 데이터 유형 검사 등)

JoGeun 2020. 4. 14. 13:53

취약점 제거는 웹 서비스 제공 환경을 고려하면 다음과 같이 당야한 단계에서 대응이 가능하다

미들웨어

실습환경의 미들웨어는 PHP이다. PHP 에서 제공하는 보안 기능을 이용하면 SQLi 대응에 부분적으로 효과가 있다

Apache 서버의 Custom, Error, Response 활성화

PHP의 Magic_quotes_gpc 설정 활성화

코드레벨

소스코드를 수정하여 대응하는 시큐어코딩 방법으로 취약점의 원인이 되는 보안약점의 근본적인 조치 및 제거가 가능하다

화이트 리스트 키워드 필터링, 데이터 유형 검사, 프리페어드 스테이트먼트 적용

DBMS

데이터베이스에서 제공하는 기능을 이용하여 취약점을 대응하는 방법이다. 주로 저장 프로시저를 이용하며 검증된 안전한 함수를 생성하여 DB질의에 사용한다

저장 프로시저 사용, 스키마 객체 접근권한 제거, DB 유저의 권한 통제

보안장비

웹 방화벽 및 IPS 등의 보안장비를 활용하여 대응하는 방법이다. 가장 빠르고 신속하게 대응이 가능하지만 근본적인 원이이 되는 애플리케이션의 취약점은 그대로 존재하기 때문에 공격 징후 탐지 등의 보안 관제와 시큐어코딩 전에 긴급 대응에 유용한 방식이다

공격 키워드 필터링

 

Apache의 Custom Error Response 활성화
Apache는 가장 많이 사용되는 웹 서버로 운영중인 사이트의 절반 가까이 채택하고 있다. 웹 서버에서 활용 가능한 보안 설정으로는 상세 에러 메시지가 노출되지 않도록 하는 "Custom Error Response"가 있다. 취약점 탐지와 데이터 획득에 활요이 불가하도록 웹 서버의 설정을 변경하여 에러 메시지가 노출되지 않도록 차단한다
PHP 미들웨어에서 "display_Errors" 설정항목을 off로 수정하면 상세 에러 메시지 노출이 차단된다.

php.ini 파일의 'display_Errors = off'로 설정하며 에러메시지가 나타나지 않는다

개발서버는 On, 운영서버는 Off로 설정하도록 권고하고 있다.

또는 커스텀 에러 처리기능을 제공하고 있으며 각 에러 코드에 대응하는 에러 페이지를 지정할 수 있다.

 

PHP의 magic_quotes_gpc 설정

SQL 인젝션 기법 중에 문자형 데이터 취약점은 싱글쿼터가 필터링 된다면 공격구문 입력에 제한이 발생한다. PHP 구 버전은 magic_quotes_gcp 기능을 사용하여 문자열 데이터 필터링이 가능하였지만 지금은 사용하지 못해도 알아두면 좋다.

GPC(Get/Post/Cookie) 작동의 magic_quotes 상태를 설정한다.

Magic_quotes가 On이면 모든 ,'(작은 따음표) "(큰 따음표) \(백슬래시) nul은 자동으로 백슬래시로 이스케이프 된다

이 설정은 PHP 5.3.0 부터 배제되었으며, PHP 5.4.0 부터는 해당 기능이 제거되어 더 이상 사용은 불가하다. 사용하더라도 필터링 우회가 가능한 방안이 알려져있고 권고하지 않는다. PHP 에서는 이와 동일한 함수로 addslashes 함수를 제공하고 있지만 이또한 우회가 가능한 문제점이 있다.

 

시큐어 코딩
SQL 인젝션 조치방안 중에 가장 효율적인 방법은 근본 원인에 해당하는 소스코드에서 취약점을 제거하는 것이다.

필터링 기법
필터링 기법은 입력 값 검증으로도 불리며 운영중인 서버에서 소스코드 수정을 최소화 하면서 취약점을 제거할 수 있는 유용한 방법중의 하나이다. 키워드 필터링 기법은 차단 리스트의 악의적인 키워드만 차단하는 블랙리스트 필터링 기법과 허용된 리스트 외에는 모든 키워드를 차단하는 화이트리스트 필터링 기법이 있다. 결론으로 화이트리스트는 히스트의 문자열을 허용하고 블랙리스트는 리스트의 문자열을 차단하는 방식이다.

블랙리스트 필터링은 악의적인 또는 금지하는 키워드가 포함되어 있는지 검사하여 차단한다.

과도한 차단은 보안성 강화 측면에서는 효과적이지만 서비스 장애 또는 사용자의 불편을 초래한다. 실제 블랙리스트 필터링을 대응방안으로 자주 사용하지는 않지만 차단 키워드는 고객사의 환경에 맞춰서 적절하게 조정할 것을 권고한다.

 

화이트리스트 필터링은 경험상 주로 파라미터의 값이 Table 또는 column 등의 객체명으로 사용될 경우에 권고한다. 허용할 테이블 또는 칼럼 명을 목록화하고 해당 목록 외에는 차단할 것을 권고한다

 데이터 유효 검사

모의해킹 프로젝트에서 데이터 타입 검사를 가장 많이 권고한다. 데이터 유형에 맞는지만 검사하면 복잡한 SQL 인젝션 키워드 필터링은 불필요하기 때문이다.

 

- 숫자형 타입

가장 많이 사용되는숫자형 타입
가장 많이 사용되는 예시는 게시물의 번호와 회원번호 등이 해당된다고 할 수 있다. 해당 데이터가 숫자인지만 검사하면 싱글쿼터 및 UNION 공격 키워드를 주입해도 취약점은 발생하지 않는다 숫자가 아닌 문자는 모두 제거되기 때문이다.
PHP는 변수를 선언할 때 타입 지정이 불가하기 때문에 PHP 계열에서 많이 발생하는 이유이기도 한다.

- 문자열 타입
문자형 데이터는 데이터에 숫자가 아닌 문자가 포함되어 있다는 의미이며 SQL 쿼리는 여기에 추가적으로 문자열 데이터 표기법에 대해서 알아야 한다. 표기법을 보면 문자열 데이터는 싱글쿼터 쌍으로 감싸서 표현하며 이 싱글쿼터를 허용할 경우 SQLi가 가능하다. 문자열 타입에서 SQLi가 가능한 근본 원이이며 제거해야 한다.
제거하는 방법으로는 문자형 데이터 구분자가 아닌 문자로 치환하는 방법이다. MySQL은 두가지 싱글쿼터 치환방법을 제공하고 있다. 첫 번째는 \(백슬래시)를 싱글쿼터 앞에추가하는 방법(addslashes)이고 두번째는 싱글쿼터를 하나더 붙여주는 방법이다. 


addslashes 함수 등을 사용하여 싱글쿼터를 이스케이프 처리를 하였을 경우 MBCS 변환이 없어야 한다는 점이다.
mb_convert_encoding 함수로 euc-kr을 utf-8로 변환하는 부분이 존재할 경우, 한 바이트 문자를 멀티 바이트로 변환할 경우 싱글 쿼터 주입이 가능한 문제가 발생합니다.
PHP에서는 addslashes 함수를 거치면서 싱글쿼터에 백슬래시가 추가되지만 특정 언어는 2바이트 문자열 중에 백슬래시와 합쳐저 하나의 문자가 될 수 있다. BF5C는 유니코드에서 하나의 문자로 변환된다 여기서 5C는 백슬래시의 hex 값이며 5C와 결합하여 하나의 문자를 이루는 방식이다.
%BF%27을 주입하면 %BF%5C%27로 변환되고 %BF%5C는 하나의 문자로 인식하여 싱글쿼터 주입이 가능해진다. 국내에서는 mb_convert_encoding 함수를 사용한 경우에 많이 발생한다

- 날짜형 타입
날짜형 타입은 2018-08-15 형태로 사용했다면 숫자와 "-"으로 구성되어 있다. 이와 같이 특정 문자만 사용하는 경우에는 해당 문자만 포함되어 있는지 검증하는 방식으로 필터링이 가능하다.
ex) Pattern patternDate= Pattern.compile("^\\d{4}-wwd{2}-wwd{2}$");

프리페어드 스테이트먼트 적용
SQL 인젝션 취약점 제거 방법 중에 프리페어드 스테이트먼트를 사용하는 방식이 가장 이상적이라고 할 수 있다.
지금까지 진행한 취약한 예제는 모두 스테이트먼트를 사용한 방식이며 이 방식은 아래의 단계를 매번 거치며 쿼리 구문을 생성한다. 이 떄문에 동적쿼리라고 부르며 매번 쿼리문을 컴파일하기 때문에 조작을 통해서 쿼리문의 구조 변경이 가능하다.

쿼리 분석 ------------- 최적화 ------------- 권한체크 ------------ 쿼리 실행

하지만 프리페어드 스테이트먼트를 사용하면 쿼리분석과 최적화 단계를 1번만 거치고 매번 실행될 때마다 재 컴파일 없이 바로 실행되기 때문에 컴파일 된 쿼리 구문의 구조 변경이 불가능하다. 

쿼리 구문의 "?"는 예약어로 플레이스 홀더라고 부른다.

플레이스 홀더를 통해서만 데이터 전달이 가능하며 조작을 통한 SQL 쿼리구문 주입은 불가능하다. 이러한 장점으로 인해 SQL 인젝션 대응방안으로 가장 많이 언급되고 있다. 하지만 이 방식은 어디까지나 신규 개발중인 서비스에 적용이 가능하며 운영중인 서비스에서 해당 방식으로 변경한다는 것은 모든 쿼리 구문을 변경해야 한다는 의미가 된다. 경우에 따라서는 적용이 불가능한 경우도 발생한다. 즉 쿼리 변경으로 인한 업무 영향도 파악에 한계가 발생한다는 의미이다. 운영중인 서비스는 데이터 유형검사 또는 필터링 기법을 적용하는 것이 최소의 자원을 투입하여 빠른 조치가 가능한 유용한 방법이다.

 

DB의 보안설정
SQL 인젝션은 근본적으로 DB에서 쿼리가 실행되기 때문에 만약 DB에서 방어가 가능하다면 매우 유용한 방안이라고 할 수 있다. 그렇지마 웹 어플리케이션에서 발생한 취약점은 DB에서 방어한다는 것은 어불성설이라고 할 수 있다.
다만 일부 기능을 이용하면 취약점으로 인한 정보 노출을 제한하거나 완화시킬 수 있다.


SQL 인젝션 취약점의 피해를 DB에서 완화시키기 위한 현실적인 방법으로 웹 애플리케이션에서 저장 프로시저를 사용하여 데이터를 조작하게 하는 방법이다. 하지만 저장 프로시저라고 무조건 안전한 것은 아니며 안전한 방식으로 구현하는 것이 중요하다. 또한 스키마 객체 중에서 테이블과 칼럼 조회가 가능한 뷰의 접근을 제한하는 방법이 있지만 아직 이 방법은 일부 DB에서는 기능을 제공하지 않는다.