보안 관련된 이슈들을 처리하다가 문득
mybatis 쿼리 처리 과정에서 #과 $가 파라미터 취급에 차이점이 있어
SQL injection을 방지하기 위해 #을 사용하는 습관을 들였던 기억이있는데
디테일하게 딱 #와 $의 차이점은 이거야! 라고 확실히 기억나지 않아
이번 기회에 찾아서 공부하게 되었다.
특성 1)
▶ #을 사용하는 경우, PreparedStatement를 생성하게 되는데 위의 ?에 파라미터가 바인딩되어 수행된다.
이렇게 파싱된 쿼리문은 재활용(캐싱)되기 때문에 효율적이다.특성 2)
▶ 변수를 String으로 인식하여 작은 따옴표(‘)가 자동으로 붙여 쿼리가 수행되기 때문에 '#{id}'와 같은 식으로 쿼리문을 작성하지 않아도 된다.
<select id="selectTest" resultType="String" parameterType="testVo">
SELECT
id AS adminId
FROM
user_info
WHERE
id = #{id}
</select>
SELECT
id AS adminId
FROM
user_info
WHERE
id = ?
특성 1)
▶ 값이 넣어진 채로 쿼리문이 수행된다. 그렇기 때문에 파라미터의 값이 바뀔 때마다 항상 쿼리문 파싱을 진행해야 한다.
( 쿼리 퍼포먼스가 떨어질 수 있음. )특성 2)
▶ 작은 따옴표(‘)가 붙지 않기 때문에 아래처럼 테이블 이름이나 컬럼 이름을 동적으로 결정할 때 사용할 수 있다.
---- ※ SQL INJECTION
<select id="selectTest" resultType="String" parameterType="testVo"> SELECT * FROM user_info WHERE id = '${id}' AND password = '${password}' </select>
만일 id 파라미터의 값으로 lgw' -- 을 입력하거나 강제로 주입하게 되면 어떻게 될까? 실제 파싱되는 쿼리문은 아래와 같을 것이다.
SELECT
*
FROM
user_info
WHERE
id = 'lgw' -- 'AND password = ''
/* 이처럼 where 절에서 비밀번호에 대한 조건은 주석처리되어 사라지게 되어
id만 입력해도 관리자 계정 정보를 조회할 수 있게 된다. */
SQL Injection 이란 악의적인 사용자가 보안상의 취약점을 이용하여,
임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위
간단하게 Spring - Mybatis 에서 # 과 $의 차이를 알아 보았다 ..
앞으로 용도를 생각하기 이전에 보안적인 목적에서라도 #을 써야겠다 편-안