자바 PreparedStatement

IT 위키
java.sql.PreparedStatement
SQL 문의 구조를 미리 정해 두고 값만 나중에 끼워 넣는 JDBC 인터페이스

SQL 문에 값이 들어갈 자리를 물음표(?)로 비워 두고 컴파일한 뒤, `setString`·`setInt` 같은 메서드로 값을 채운다. 값은 데이터로만 전달되므로 SQL 문의 구조를 바꿀 수 없다.

Statement 와의 차이

[편집 | 원본 편집]
  • Statement : 문자열을 이어 붙여 완성한 SQL 을 그대로 보낸다. 값에 따라 문장 구조가 바뀔 수 있다
  • PreparedStatement : 구조를 먼저 고정하고 값을 따로 보낸다. 같은 문장을 반복 실행할 때 컴파일 결과를 재사용해 성능도 낫다

SQL 인젝션 대응

[편집 | 원본 편집]

문자열을 이어 붙이면 값이 SQL 문법의 일부가 된다.

   // 취약한 코드
   String query = "select * from member a where gubun = '" + a.gubun + "'";

`gubun` 에 `a' or 'a'='a` 를 넣으면 조건이 항상 참이 되어 테이블 전체가 조회된다. PreparedStatement 는 이 입력을 값 하나로만 취급하므로 따옴표가 문법으로 해석되지 않는다.

   // 대응한 코드
   String query = "select * from member a where gubun = ?";
   PreparedStatement pstmt = conn.prepareStatement(query);
   pstmt.setString(1, a.gubun);
  • 파라미터를 받는 부분은 상수 문자열로 정의해야 한다. 그 안에 입력값을 이어 붙이면 효과가 없다.
  • 테이블명·컬럼명·ORDER BY 방향은 파라미터로 바인딩할 수 없다. 이런 값은 허용 목록으로 검증한다.
  • 저장 프로시저 안에서 문자열을 이어 붙여 동적 SQL 을 만들면 여전히 취약하다.

같이 보기

[편집 | 원본 편집]