Mybatis를 사용하면서 value를 전달할 때 나는 오로지 #{}을 사용했었다.
db정보를 깃에 올릴때 제외하기 위해서 방법을 알아보던 중
아래처럼 ${}을 사용해서 값을 받아오는 것을 발견하게 되어서 이 둘의 차이점을 찾아보게되었다.
- Mapper
SELECT * FROM MEMBER WHERE ID = #{ID} and PW = #{PW}
매퍼에서 이러한 쿼리를 mysql로 보낸다고 가정하면
- Mysql
SELECT * FROM MEMBER WHERE ID = ? and PW = ?
Mysql은 이런식으로 받아오게되고 컴파일한다
- 실제 실행시
SELECT * FROM MEMBER WHERE ID = 'json' and PW = 'ihatehim2'
실제 실행시 이렇게 변경이 되어서 받아진다
- Mapper
SELECT * FROM MEMBER WHERE ID = '${ID}' and PW = '${PW}'
${}는 상수값을 그대로 받아오기 때문에 '가 자동생성되지 않음
문자열을 받아올 땐 직접 ' 를 적어주어야함
- Mysql
SELECT * FROM MEMBER WHERE ID = 'json' and PW = 'ihatehim2'
Mysql은 이런식으로 받아오게되고 컴파일한다
- 실제 실행시
SELECT * FROM MEMBER WHERE ID = 'json' and PW = 'ihatehim2'
# { }
- 값에 ' '가 자동으로 붙음
- PreparedStatement 통해 악의적인 쿼리주입을 예방할 수 있음
- 보완차원에서 유리
- 주로 사용자의 입력을 전달할때 사용
$ { }
- ' '가 자동으로 붙지않음
- Statement 방법으로 파라매터가 출력되어서 전달됌
- 의도적인 쿼리주입을 막을 수 없음
- SQL injection 보안 위험 발생 가능
- 주로 table명 column명 전달시 사용
WHERE 절을 강제로 참으로 만들어 SQL을 조작하는 방법
SELECT * FROM MEMBER WHERE ID = ''or 1=1--' and PW = '아무거나입력'
- ID : 'or 1=1-- 입력시
- 앞에있던 '표는 id에 입력한 '에 의해 상쇄되고 거짓이된다
- 1=1은 항상 참이고 or 때문에 둘중 하나가 참이면 참
- -- 뒤는 주석처리가 된다
- 비밀번호는 주석처리가 되고 아무거나 입력해도 상관없다
따라서 Where 절이 참이 되고 id값은 database에서 가장 최상단에 있는 id가 선택된다.