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# 형태로 받도록 수정한다.
'04. 시큐어코딩' 카테고리의 다른 글
시큐어코딩(20) - External Control of System or Configuration Setting (0) | 2017.11.22 |
---|---|
시큐어코딩(19) - LDAP Manipulation (0) | 2017.11.22 |
시큐어코딩(17) - SQL Injection: Persistence (0) | 2017.11.18 |
시큐어코딩(16) - SQL Injection: JDO (0) | 2017.11.18 |
시큐어코딩(15) - Reliance on Untrusted Inputs in a Security Decision (0) | 2017.11.18 |