SQL Injection 대응 방안


1) 동적 SQL사용 지양

데이터베이스와의 연동 부분에서는 동적 SQL을 더 이상 사용하지 말고 저장 프로시저를 사용해야 한다[1][2]. 지금까지도 많이 사용되고 있는 동적 SQL 완성 방식은 변수의 입력값을 연결시켜 SQL문을 완성(Concatenation of SQL)시키는 형태이므로 공격자의 SQL문 주입이 매우 용이하다. 그러나 저장 프로시저를 통해 데이터베이스 연동을 구현한다면, 이미 프로시저 내부에서 입력값에 대한 자료 형검증이 이루어진다. 또한 해당 프로시저의 내부에서만 영향을 끼치기 때문에 보안 측면에서도 더욱 더 안전하고, 성능이나 유지보수 측면에서도 대단히 효과적이다.


2) 안전한 웹 사이트 설계와 구현


SQL Injection 취약점은 입력값 검증 절차 문제에 기인하므로, 개발단계에서부터 반드시 모든 입력값에 대해 적절한 검증절차를 설계하고 구현해야 한다.

예를 들어 게시판의 이름을 처리해야 하는 페이지가 있다면 게시판 이름에 대한 입력값에 대해 다음의 예시와 같이 검증 할 수 있다. 간략히 검증과정을 요약하면, 입력값의 크기를 검사하고 특수문자가 있는 경우 위험하지 않은 문자로 치환한 후 입력값이 허용범위 내에 존재하는지 검사하는 방식이다.

■ 게시판 이름 처리용 검증 함수 예시
입력값을 전달받을 변수를 선언하고 가장 먼저 LenStr함수를 사용하여 입력값이 10자 이내인지 검증한다.

Dim bbstitle :
bbstitle = (InputFilter(ReplaceChar(LenStr(Request.QueryString("title"),10)))


■ 특수문자 치환 함수 예시

입력값에 부적절한 특수문자가 있는지 검사하여 서버나 브라우저에서 실행되지 않는 안전한 코드로 치환한다. 예를 들어 작은따옴표(') 나 부등호(<,>)를 입력 하더라도 HTML에서 표현가능한 문자 코드로 치환되므로 서버나 브라우저에서는 프로그램의 일부로써 실행되지 않고 화면에 표시만 한다. 그러므로 정상적인 접속자의 입장에서는 웹 브라우저에서 동일하게 나타내 주기 때문에 불편함이 없다.(http://www.w3.org/TR/html4/charset.html#h-5.3.2)

Function ReplaceChar(str)
        ReplaceChar = ""
        If str <> "" Then
              str = replace(str, "<", "&lt")
              str = replace(str, ">", "&gt")
              str = replace(str, """, "&#34;")
              str = replace(str, "|", "&#124;")
              str = replace(str, "$", "&#36;")
              str = replace(str, "%", "&#37;")
              str = replace(str, "'", "&#39;")
              str = replace(str, "/", "&#47;")
              str = replace(str, "(", "&#40;")
              str = replace(str, ")", "&#41;")
              str = replace(str, ",", "&#44;")
        End If
       ReplaceChar = str
End Function


■  허용 범위 검증 함수 예시

입력값이 적절한 허용 범위에 속하는지 확인하는 함수이다. 허용할 범위만 정의하여 그 외의 입력값은 모두 예외처리 하는 구조이므로 공격 패턴의 변화에 의존적이지 않다.

Function InputFilter(str) ' 정수, 알파벳, &, #, ; 만 허용
        Dim i, ret
        ret = TRUE
            For i = 1 To Len(str)
                If Not((Asc(Mid(str, i, 1)) >= 48 And Asc(Mid(str, i, 1)) <= 57) Or
                (Asc(Mid(str, i, 1)) >= 65 And Asc(Mid(str, i, 1)) <= 90) Or
                (Asc(Mid(str, i,1)) >= 97 And Asc(Mid(str, i, 1)) <= 122) Or
                Asc(Mid(str, i, 1)=35 Or Asc(Mid(str, i, 1)) = 38 Or Asc(Mid(str, i, 1)) = 59) Then
                        ret = FALSE
                End If
        Next
        If ret = TRUE Then titlecheck = str
        Else titlecheck = 0
                Response.Write "<script>alert('부적절한 값이 입력되었습니다.');
                history.back();</script>"
        Response.End
        End If
End Function

만약 이러한 허용범위 명시방식 또는 White List로 검증하는 Positive Filtering 방식으로 검증하지 않고, 거부나 차단 대상을 나열하는 허용불가 명시방식 또는 Black List로 검증하는 Negative Filtering 방식으로 구현 한다면 지속적으로 거부할 대상을 일일이 추가 해 주어야 하는 어려움이 발생한다.

그러므로 반드시 허용할 대상을 명시하고 그 이외의 경우는 예외처리를 해야 시간이나 비용면에서도 훨씬 효과적이다.


3) 웹 서버 보안 강화


SQL Injection에 대한 근본적인 문제 해결을 위해서는 프로그램 보완 조치가 반드시 필요하지만, 웹 서버의 보안 강화 설정을 통해서도 보완적인 효과를 볼 수 있다.

■ 자세한 오류 내용 표시 차단
IIS 웹 서버에서는 기본적으로 웹 서비스의 오류가 발생 할 때, 자세한 오류 메시지를 접속자에게 표시하게 되어 있다. 그러므로 이 설정을 변경하여 공격자가 오류 메시지를 통해 유용한 정보를 수집할 수 없도록 수정해야 한다.

사용자 삽입 이미지

일반적인 SQL Injection 공격의 경우 오류 메시지를 기반으로 정보를 추출하게 되므로, 이 설정 변경만으로도 방어효과를 볼 수 있다. 다만, Blindfolded SQL Injection[1]이나 시스템 명령어를 수행하는 SQL Injection공격은 차단할 수 없으므로 반드시 프로그램 수정의 보완조치로 활용해야 한다.

■ SQL 서버 보안 강화
웹 페이지와 MS-SQL 서버를 연동 할 때, 데이터베이스의 관리자 계정인 SA 계정을 사용하게 되면 공격자가 악용할 수 있으므로 매우 위험하다. 그러므로 반 드시 사용자 계정을 사용하고 최소 권한만을 할당하여 사용해야 한다.

또한, 앞서 분석한 공격 스크립트의 경우 시스템 테이블인 Syscolumns와 Sysobjects의 정보를 이용하고 있으므로, 반드시 필요하지 않은 경우라면 사용자 계정이나 "public"계정에 할당되어 있는 “SELECT” 권한을 제거하는 것이 안전하다.

사용자 삽입 이미지

만약 특정 사용자 계정에 대해서 Sysobjects 및 Syscolumns 시스템 테이블에 대한 "SELECT" 권한을 다시 부여하려면 아래와 같이 실행하면 된다.

use <사용자데이터베스명>
        go
        GRANT SELECT ON sysobjects TO userid
        GRANT SELECT ON syscolumns TO userid
        go

위의 명령을 실행하면 "userid"라는 사용자계정에 대해서 Sysobjects 및 Syscolumns 테이블에 대한 "SELECT" 권한을 제한하게 되며, 해당 사용자계정에서 Sysobjects나 Syscolumns 시스템 테이블 조회 시 다음과 같은 오류와 함께 실패하게 된다.

    [오류메시지]
    서버: 메시지 229, 수준 14, 상태 5, 줄 1
    'dbo' 소유자, 'pubs' 데이터베이스, 'sysobjects' 개체에 대한 SELECT 사용 권한이
    거부되었습니다.

만약 특정 사용자 계정에 대해서 Sysobjects 및 Syscolumns 시스템 테이블에 대한 “SELECT” 권한을 다시 부여하려면 아래와 같이 실행하면 된다.

    use <사용자데이터베스명>
        go
        GRANT SELECT ON sysobjects TO userid
        GRANT SELECT ON syscolumns TO userid
        go


4) 웹 방화벽 활용

웹보안 취약점의 근본적인 문제 해결을 위해서는 프로그램의 보완조치가 반드시 필요하다. 하지만 운영 중인 홈페이지에서 프로그램 수정으로 인한 문제들도 검토하여 조치해야 하기 때문에, 그 시간 동안은 웹방화벽이나 부가적인 보완조치들을 통해 시간을 확보 할 수 있다.

예를 들어 윈도우즈의 IIS 환경이라면 URLScan이나 공개웹방화벽 WebKnight[2]를 활용하여 보안수준을 향상시킬 수 있다. 특히 WebKnight의 경우는 KrCERT/CC의 공개웹방화벽 안내 페이지[3]에서 각종 가이드와 표준 정책 및 기술지원도 제공 하고 있다.

참고로 이번 분석에서 언급한, 쿠키에 대한 SQL Injection공격을 차단하기 위해서는 반드시 그림과 같이 해당 기능을 활성화해야 한다.

사용자 삽입 이미지

HTTP 헤더의 특성 상 특수문자가 많이 사용 되므로, 차단 설정 후에는 일정기간 동안 로그 모니터링을 통해 서비스에 문제가 없는지 확인해야 한다.

하지만, 어디까지나 웹 방화벽은 보완 장치로 활용해야 하며, 프로그램 수정조치 등의 근본적인 원인 제거가 반드시 수행되어야 한다. 예를 들어 전쟁에 나간 병사가 아무리 튼튼한 갑옷을 입었더라도 건강하지 않거나 기본 체력이 충분치 않다면 결국 그 갑옷조차 무용지물이 될 것이다.

5) 웹보안 취약점 점검

설계와 구현에 있어서 안전한 개발 절차에 따라 개발되었더라도 존재할 수 있는 보안 문제들을 점검하고 진단하는 과정이 필요하다.

특히 SQL Injection의 경우는 프로그램 소스 상에서 입력값 검증이 적절히 이루어졌는지 점검(White box test) 해 보고 웹 취약점 점검 도구를 병행하여 점검(Black box test)해 본다면 더욱 더 안전한 웹 서비스 운영이 될 것이다.

예를 들어 마이크로소프트에서 제공하는 소스코드 검사 도구인 Microsoft Source Code Analyzer for SQL Injection[1]을 활용하거나, 윈도우즈 내장 명령어인 "findstr"을 통해 외부로부터 입력 받는 데이터가 검증 함수를 거치는 지 확인해 볼 필요가 있다.

아래의 점검 예제는 "findstr" 명령어를 사용하여 입력값을 받는 프로그램 소스부분을 검사하는 예제이다. 아래의 예시대로 검사하면 입력값 검증 함수를 동일 행에서 처리 하지 않는 경우를 찾아 볼 수 있다.

    findstr /I /S /G [request객체목록] *.asp | findstr /I /V "[입력값검증함수명]"
    예) findstr /I /S /G arglist.txt *.asp | findstr /I /V "inputfilter\("

    arglist.txt
    request.form
    request.QueryString
    request.ServerVariables
    request.Cookies
    request\(

그리고 웹 취약점 점검 도구를 사용해서 진단해 볼 수도 있는데, 웹보안 점검 도구는 sectools.org나 NIST 홈페이지 등에서 소개하고 있다. 또한, PAROS, N-Stealth, Scrawlr, Wikto 등의 무료 점검도구들을 활용하여 점검 해 볼 수 있다.

그리고 KrCERT/CC에서 제공하는 원격 웹 취약점 점검 서비스를 이용하면 웹 취약점 원격 점검 서비스를 제공 받을 수 있으며, 점검 신청은 홈페이지(http://webcheck.krcert.or.kr/) 에서 접수 받고 있다. 다만, 비영리단체나 영세기업 등 정보보호취약계층을 대상으로 제공하므로 서비스 대상에 해당 하는 경우에만 서비스 받을 수 있다.
Posted by n3015m
:
BLOG main image
'네오이즘'의 보안LAB 블로그입니다........... n3oism@gmail.com by n3015m

카테고리

분류 전체보기 (228)
[ HappyDevTool ] (29)
[ HappyToolRelease ] (4)
[Book] (6)
[ Security Studies ] (0)
- CII (2)
- BigData (2)
- Web Hacking (10)
- SQL Injection (25)
- Mobile Security (9)
- Network (6)
- OperatingSystem (4)
- Malware & Reversing (4)
- Phishing (5)
- Compliance (0)
- Programming (13)
- Tools (13)
- IoT (6)
- etc (21)
[Pentration Testing] (3)
[OS X] (4)
[ Security Trends ] (16)
[ Fixing Guideline ] (7)
My Way, My Life (34)
About Me (2)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

Total :
Today : Yesterday :