Prepared Statement (with Parameterized Query)
SQL Statement를 미리 준비해두고, Parameter를 입력받아 Statement에서 사용한다. 이 방법은 Code와 Data를 분리할 수 있도록 하며, 공격자가 SQL Statement의 목적을 바꿀 수 없도록 한다.
String custname = request.getParameter("customerName");
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, custname);
ResultSet results = pstmt.executeQuery( );
custname에 SQL Injection을 시도해도 해당 입력 전체를 string으로 받아서 처리하기 때문에 Statement의 행동이 변경되지 않는다.
Stored Procedure
SQL Injection에 대한 완벽한 방어 기법은 아니지만, Prepared Statement와 같은 효율을 낼 수 있다.
Stored Procedure에서 안전하지 않은 동적 SQL 생성을 포함하지 않았을 경우
String custname = request.getParameter("customerName"); // This should REALLY be validated
try {
CallableStatement cs = connection.prepareCall("{call sp_getAccountBalance(?)}");
cs.setString(1, custname);
ResultSet results = cs.executeQuery();
// … result set handling
} catch (SQLException se) {
// … logging and error handling
}
White LIst
특정 값의 Parameter만 허용하는 방법으로, 모든 케이스에서 부차적인 보호 기법으로 사용하는 것이 좋다.
Escaping Input
User로 부터 받는 모든 값들에 대해서 Escape를 진행한다.