(mybatis) # 과 $의 차이

lgw2236·2023년 3월 27일
0

개발기록

목록 보기
5/8
post-thumbnail

보안 관련된 이슈들을 처리하다가 문득
mybatis 쿼리 처리 과정에서 #과 $가 파라미터 취급에 차이점이 있어
SQL injection을 방지하기 위해 #을 사용하는 습관을 들였던 기억이있는데
디테일하게 딱 #와 $의 차이점은 이거야! 라고 확실히 기억나지 않아
이번 기회에 찾아서 공부하게 되었다.

1. "#" ?

특성 1)

▶ #을 사용하는 경우, PreparedStatement를 생성하게 되는데 위의 ?에 파라미터가 바인딩되어 수행된다.
이렇게 파싱된 쿼리문은 재활용(캐싱)되기 때문에 효율적이다.

특성 2)  

▶ 변수를 String으로 인식하여 작은 따옴표(‘)가 자동으로 붙여 쿼리가 수행되기 때문에 '#{id}'와 같은 식으로 쿼리문을 작성하지 않아도 된다.

XML 예시SQL문 (#)

<select id="selectTest" resultType="String" parameterType="testVo">
    SELECT
        id AS adminId
    FROM
        user_info
    WHERE
        id = #{id}
</select>

Mybatis 파라미터 인식 (#)

SELECT
    id AS adminId
FROM
    user_info
WHERE
    id = ?

2. "$" ?

특성 1)

▶ 값이 넣어진 채로 쿼리문이 수행된다. 그렇기 때문에 파라미터의 값이 바뀔 때마다 항상 쿼리문 파싱을 진행해야 한다.
( 쿼리 퍼포먼스가 떨어질 수 있음. )

특성 2)  

▶ 작은 따옴표(‘)가 붙지 않기 때문에 아래처럼 테이블 이름이나 컬럼 이름을 동적으로 결정할 때 사용할 수 있다.

XML 예시SQL문 ($)

---- ※ SQL INJECTION

<select id="selectTest" resultType="String" parameterType="testVo">
     SELECT
        *
    FROM
        user_info
    WHERE
        id = '${id}' AND password = '${password}'
</select>

만일 id 파라미터의 값으로 lgw' -- 을 입력하거나 강제로 주입하게 되면 어떻게 될까? 실제 파싱되는 쿼리문은 아래와 같을 것이다.

Mybatis 파라미터 인식 ($)

SELECT
    *
FROM
    user_info
WHERE
    id = 'lgw' -- 'AND password = ''
    
    /* 이처럼 where 절에서 비밀번호에 대한 조건은 주석처리되어 사라지게 되어
    id만 입력해도 관리자 계정 정보를 조회할 수 있게 된다. */

참조 ) SQL INJECTION

SQL Injection 이란 악의적인 사용자가 보안상의 취약점을 이용하여,
임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위

간단하게 Spring - Mybatis 에서 # 과 $의 차이를 알아 보았다 ..
앞으로 용도를 생각하기 이전에 보안적인 목적에서라도 #을 써야겠다 편-안

profile
어제보다 오늘 더

0개의 댓글