본문 바로가기
04. 시큐어코딩

시큐어코딩(18) - SQL Injection: mybatis Data Map

by 김덕환 2017. 11. 18.
반응형

1. 정의


SQL 삽입공격 : mybatis Data Map(SQL Injection: mybatis Data Map)


외부에서 입력된 값이 질의어의 인자값으로만 사용되지 않고, 질의 명령어에 연결되는 문자열로 사용되면, 공격자가 의도하지 않았던 문자열을 전달함으로써 질의문의 의미를 왜곡시키거나 그 구조를 변경하여 임의의 데이터베이스 명령어를 수행할 수 있다.



2. 해결방법


- 외부의 입력으로부터 위험한 문자나 의도하지 않았던 입력을 제거하는 코드를 프로그램 내에 포함시킨다.

- mybatis Data Map 파일의 인자를 받는 질의 명령어 정의시에 문자열 삽인 인자($...$)를 사용하지 않는다. 즉 #<인자이름># 형태의 질의문을 사용한다.



3. 예제


========================== 안전하지 않은 코드의 예 ==========================


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="Student">

<resultMap id="StudentResult" class="Student">

<result column="ID" property="id" />

<result column="NAME" property="name" />

</resultMap>

<select id="listStudents" resultMap="StudentResult">

SELECT NUM, NAME

FROM STUDENTS

ORDER BY NUM

</select>

<select id="nameStudent" parameterClass="Integer" resultClass="Student">

SELECT NUM, NAME

FROM STUDENTS

WHERE NUM = #num#

</select>

<!-- dynamic SQL 사용 -->

<delete id="delStudent" parameterClass="Student">

DELETE STUDENTS

WHERE NUM = #num# AND Name = '$name$'

</delete>

</sqlMap>


============================================================================


위의 예제는 mybatis Data Map에서 사용하는 질의문 설정파일(XML)이다. 정의된 질의문 중 delStudent 명령어 선언에서 질의문에 삽입되는 인자들 중 $name$으로 전달되는 문자열 값은 그대로 연결되어 질의문이 만들어진다. 다라서 만약 name의 값으로 ' OR 'x'='x'을 전달하면 다음과 같은 질의문이 수행되어 테이블의 모든 원소를 삭제하게 된다.

(DELETE STUDENTS WHERE NUM = #num# and Name = '' OR 'x'='x')



============================== 안전한 코드의 예 =============================


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="Student">

<resultMap id="StudentResult" class="Student">

<result column="ID" property="id" />

<result column="NAME" property="name" />

</resultMap>

<select id="listStudents" resultMap="StudentResult">

SELECT NUM, NAME

FROM STUDENTS

ORDER BY NUM

</select>

<select id="nameStudent" parameterClass="Integer" resultClass="Student">

SELECT NUM, NAME

FROM STUDENTS

WHERE NUM = #num#

</select>


<!-- static SQL 사용 -->

<delete id="delStudent" parameterClass="Student">

DELETE STUDENTS

WHERE NUM = #num# AND Name = '#name#'

</delete>

</sqlMap>


============================================================================


위의 코드처럼 Name 인자를 #name# 형태로 받도록 수정한다.

반응형