Coding/Secure coding

SQL 인젝션

코딩; 2022. 1. 23. 13:29

˙  SQL 인젝션이란?

웹 애플리케이션에서 외부 입력 데이터를 삽입하며 DB쿼리문을 생성하고 실행하는 경우, 조작된 입력값으로 데이터베이스로전달되는 쿼리(CRUD)를 변조하여 데이터베이스에 불법적인 데이터 열람, 삭제, 시스템 명령 수행 등이 발생하는 취약점이다.

 

˙  SQL 인젝션 발생원인

애플리케이션에서 SQL 쿼리문의 일부로 사용되는 사용자의 입력값에 대한 적절한 검증 작업을 수행하지 않고,

동적으로 쿼리를 생성해서 사용하는 경우 발생한다.

SQL 인젝션 취약한 사이트의 경우 이미 존재하는 admin 아이디에 대해 쿼리문을 조작하여 로그인 할 수 있다.

아이디: admin'# 
비밀번호: #
만을 가지고 로그인 될 수 있다.

이 문제를 해결하기 위해 mysql이나 오라클의 경우 '# 를 붙여 password부분을 코멘트 처리할 수 있다.

 

SQL 인젝션 취약점 제거를 위한 시큐어 코딩 방법으로 '정적쿼리'를 사용한다.

 

▶ MyBatis 사용시 SQL삽입 취약점을 가지는 코드

<select id="getPerson" parameterType="String" resultType="org.application.vo.Person">
	SELECT *
    FROM PERSON
    WHERE NAME LIKE '${NAME}'
</select>

▶ MyBatis 사용시 SQL삽입 취약점 제거

<select id="getPerson" parameterType="String" resultType="org.application.vo.Person">
	SELECT *
    FROM PERSON
    WHERE NAME = #{NAME}
</select>

단순히 NAME에 ''를 제거하고 #을 붙여주면 된다.

 

MyBatis에서 $라는 메타문자를 사용해서 파라미터 값을 맵핑하게 되면 먼저 입력값을 집어넣고 그 다음에 쿼리를 분석해서 명령어를만들고 실행하는 순서대로 쿼리가 수행되는 반면, #이란 부호를 사용해서 외부 데이터를 넘겨받게 되면 먼저 쿼리문을 분석하고 명령어를 만들어 놓고 그 다음에 들어오는 자료형을 가지고 데이터를 연결해서 실행하는 구조로 처리가 된다. 

 

이렇게 됨으로 해서 쿼리 명령어 먼저 만들어지고 나서 자료형을 가지고 데이터가 연결되어서 사용되기 때문에 sql삽입이 발생되지 않은 코드 패턴이 된다.