Spring mybatis에서 #{ }문법과 ${ }문법의 차이점(feat. SQL Injection)

안녕하세요. 오늘 공유할 내용은 Spring mybatis에서 사용하는 #{} 문법과 ${} 문법의 차이와 ${}문법을 사용했을때 발생할 수 있는 SQL Injection이라는 해킹 방법에 대하여  내용을 공유하고자 합니다. 


먼저 Spring이란 웹개발을 할때 기업에서 주로 사용하는 프레임워크로 전자정부 프레임워크로 지정되어 사용되는 우리나라에서 개발하는 사람들은 대부분 거쳤을 만큼 대중적인 프레임워크입니다. 그중에서 JDBC를 사용하여 DB와 연동하는 것으로 MyBatis라는 라이브러리를 사용하게 됩니다. 그중에서 VO나 DTO를 매개변수로 하여금 데이터의 이동을 하게하는데요. 그 기능으로 $와 #문법이 있습니다.


즉, VO에 name이라는 변수가 있고 getter가 getName()이라는 메소드로 되어 있을때, #{name}을 하거나 ${name}을 하게되면 VO에있는 name값이 MyBatis의 XML에 파싱될때 getName한 값이 오게됩니다.


#{ }

- Parameter가 String 형태로 들어와 자동적으로 'Parameter' 형태가 된다.

- 예를들어, VO에 담긴 z_myid값이 getter로 반환될 때, z_myid값이 123이라면 mybatis 쿼리에는 z_userid='123'의 형태가 된다.

- SQL Injection을 예방할 수 있어 보안측면에서 유리하다.


${ }

- Parameter가 바로 출력된다.

- 예를 들어, VO에 담긴 z_myid값이 getter로 반환될 때, z_myid값이 123이라면 mybatis 쿼리에는 z_userid=123의 형태가 된다.

- SQL Injection을 예방할 수 없어 보안측면에서 불리하다.


sql injection 

- SQL인젝션은 응용 프로그램 보안 상의 허점을 의도적으로 이용해, 악의적인 SQL문을 실행되게 함으로써 데이터베이스를 비정상적으로 조작하는 코드 인젝션 공격방법이다. ${}문법을 사용하면 주로 발생할 수 있는 가장 큰 허점이었으며 이를 막기위해 대부분 #{} 문법을 사용함으로써 대처한다.


SQL Injection Example

- 사용자가 ID와 PASSWORD를 입력하는 상황일 경우 Mabatis에 다음과 같이 쿼리가 있다고 할때,

" select * from  tblUserInfo where userid = '${userid}' and userpw = '${userpw}' "

악의적인 유저(아이디 비밀번호를 모르는)가 비밀번호를 [password' OR 1=1 limit 1--] 라고 입력하게 되는 경우 단, 비밀번호는 암호화처리가 되어있지 않다고 가정!

" select * from tblUserInfo where userid = 'admin' and userpw = 'password' OR 1=1 limit 1-- ' "

쿼리 결과는 올바르지 못한 결과로 작동하게 된다. 

싱글쿼테이션(')으로 감싸도 끝에 있는 싱글쿼테이션 1개가 -- 주석처리되고 1=1이라는 조건이 absolutely true로 만들기 때문에 홈페이지에 작성된 쿼리에 따라 sql Injection으로 충분히 해킹이 가능할 수 있다.


참조사이트 : https://ko.wikipedia.org/wiki/SQL_%EC%82%BD%EC%9E%85

댓글

Designed by JB FACTORY