오늘은 mybatis 에서 혼동되기 쉬운
#{} 와 ${} 에 대해서 이야기해 보도록 하겠습니다
mybatis 란?
Java 를 위한 오픈 소스 SQL 매핑 프레임워크
SQL Query 의 실행 결과를 Java 객체와 맵핑하는 기능을 제공하고
조건에 따라 SQL 문을 동적으로도 생성할 수 있는 기능을 제공하며
SQL 을 Java 코드와 분리하여 XML 파일이나 어노테이션을 통해 관리한다
따라서, 개발자 입장에서 SQL 문을 쉽게 작성하고 관리할 수 있고
JDBC 로 처리되는 상세한 작업들을 추상화기에
SQL 관리를 직관적으로 만들며 유지보수 측면에서도 효율적이다
(Query 실행, 결과 매핑, 트랜잭션 관리 등등)
'#{}' (Parameter Binding)
PreparedStatement 의 바인딩 방식과 유사하다
(PreparedStatement 에 대한 설명 보러 가기)
Query 가 실행되기 전 mybatis 는
#{} 를 해당 파라미터의 값으로 대체하고
JDBC 의 '?' 플레이스홀더로 변환하여 직접 Query 에 포함시키지 않고
별도의 값으로 전달하기에 SQL Injection 에 대해서 안전하다
'1' OR '1' = '1' 과 같은 입력을 하더라도, Query 에 직접 삽입되지 않고
이를 문자열 값 하나로 인식하고 처리하므로 쿼리의 논리를 변경할 수 없다
하지만 동적인 SQL 요소에는 적합하지 않다
(테이블 이름, 칼럼 이름 등등)
#{} 를 이용한 SQL Injection 예시
/** mapper */
SELECT * FROM user WHERE id = #{userId}
/** SQL */
SELECT * FROM user WHERE id = ?
/** SQL Injection Attempt */
SELECT * FROM user WHERE id = '1' OR '1'='1' /** SQL Injection fail */
'${}' (String Substitution)
문자열 치환을 통해 파라미터의 값을 Query 에 직접 삽입한다
mybatis 가 별도의 검증 과정을 거치지 않고
파라미터의 값이 Query 의 일부로 해석되기 때문에
SQL Injection 에 취약할 수 있다
'1' OR '1' = '1' 과 같은 입력 한다면, Query 에 직접 삽입되어
원래 의도와 달리 쿼리의 논리가 변경될 수 있다
동적인 SQL 요소에 유용하지만
SQL Injection 방지를 위한 검증 단계가 별도로 필요하다
${} 를 이용한 SQL Injection 예시
/** mapper */
SELECT * FROM user WHERE id = '${userId}'
/** SQL */
SELECT * FROM user WHERE id = 'actualData'
/** SQL Injection Attempt */
SELECT * FROM user WHERE id = '1' OR '1'='1' /** SQL Injection success */
'Web Technologies 🖥️ > spring' 카테고리의 다른 글
간단한 게시글 조회수 어뷰징 방지 (쿠키, 세션, ip 사용 X) - [Spring] (46) | 2023.11.13 |
---|