SQL Injection이란
웹 애플리케이션에서 데이터의 유효성 검증을 하지 않아, 개발자가 의도하지 않은 동적 쿼리(Dynamic Query)를 생성하여 조작된 SQL문으로 DB 정보를 열람하거나 변경할 수 있는 보안 취약점
대표 예시
SELECT * FROM user Where userId = '${userId}' and userPw = '${userPw}'
위의 경우에 ${userPw}에 pw' or 1=1 값을 입력하면
SELECT * FROM user Where userId = 'valideUserId' and userPw = 'pw' or 1=1
실행되어 id만 알아도 로그인이 되는 현상이 발생할 수 있다.
이러한 현상을 방지하기 위해서 DB layer에서 Prepared Statement 기능을 제공한다.
이미 지정된 sql을 이용하여 DB에서 실행계획을 생성해 두고 파라미터로 바인딩된 값은 단순히 String으로만 치환해서 실행하는 것이다.
위의 대표 예시에서는 공격자가 지정한 pw' or 1=1 값이 단순히 String으로만 대입되는 것이다.
SELECT * FROM user Where userId = 'valideUserId' and userPw = '\'pw\' or 1=1'
추가적으로 Prepared Statement를 사용하면 DB 입장에서는 미리 실행계획도 짜놓을 수 있어서 효율이 더 좋아진다고 한다.
Mybatis
mybatis를 사용하는 경우에는 주의할 점으로는
파라미터 바인딩을 사용할때 ${}를 사용하지 않고 #{}를 사용해야 한다.
#{}를 사용해야 Prepared Statement 기능을 제공
${}은 보통 동적 sql 실행 시 사용이 된다.
조회할 table명을 동적으로 변경해야 하는 경우..
JPA에서는 기본으로 Prepared Statement를 지원한다고 한다.