${tableName}
이라고 쓰고, tableName 변수에 users라는 값이 있는 경우SELECT * FROM users
가 됨#{userId}
라고 쓰면, 실제 쿼리는 SELECT * FROM users WHERE id = ?
가 되고, userId 변수의 값은 별도로 쿼리에 삽입String query = "SELECT * FROM users WHERE username = '" + username + "'";
username
변수에 "admin' --"
와 같은 값이 들어간다면, 최종 쿼리는 "SELECT * FROM users WHERE username = 'admin' --'"
가 되어 SQL 주석을 이용한 인젝션 공격이 가능#{변수}
는 ?
(placeholder)로 대체"SELECT * FROM users WHERE id = #{userId}"
라는 쿼리는 "SELECT * FROM users WHERE id = ?"
로 변환#{변수}
에 해당하는 자리에 실제 변수의 값을 바인딩함?
자리에는 안전하게 바인딩된 실제 값이 들어 감PreparedStatement pstmt = connection.prepareStatement("SELECT * FROM users WHERE username = ?");
pstmt.setString(1, username);
username
에 "admin' --"
가 들어가도, 이 값은 문자열 데이터로 처리되어 쿼리의 구조를 변경할 수 없음