[JDBC] Statement | PreparedStatement

JTI·2023년 5월 28일
0

🗂️ DB | SQL

목록 보기
3/5
post-thumbnail

💡 Statement


✔️ SQL문을 실행할 때 사용하는 인터페이스

⚙️ statement의 동작 방식

✏️ 파싱 트리

  • SELECT문은 DBMS 내부적으로 4단계의 과정(Parse, Bind, Execute, Fetch)을 거쳐 결과를 출력한다.
    ➡️ 구문 분석을 하는 parse 과정을 거치면 파싱 트리가 생성된다.

  • 매번 쿼리를 수행할 때마다 4단계를 거치게 됨(계속적으로 단계를 거치면서 수행)

  • 구문 분석(parse)부터 인출(fetch)까지 모든 과정을 매번 수행
    ➡️ 따라서 입력값에 SQL구문에 영향을 미치는 특수문자나 예약어가 들어갈 경우 구문 분석 과정에서 SQL구문의 일부로 작용하여 SQL Injection 공격이 가능하다.
    ➡️ 보안 취약

💡 PreparedStatment


✔️ 데이터베이스 관리 시스템(DBMS)에서 동일하거나 비슷한 데이터베이스 문을 높은 효율성으로 반복적으로 실행하기 위해 사용되는 기능

  • PreparedStatement는 Statement를 상속하고 있는 Interface

⚙️ PreparedStatement의 동작 방식

  • 구문 분석(parse) 과정을 최초 1회만 수행하여 생성된 결과를 메모리에 저장해 필요할 때마다 사용

  • 미리 구성된 파싱 트리를 반복적으로 사용하기 때문에 Statement에 비해 시간을 단축할 수 있다.

  • SQL구문이 미리 컴파일 되어 사용자 입력값을 변수로 선언해 값을 대입하여 사용한다.
    ➡️ 외부 입력값으로 SQL문법에 영향을 미치는 특수문자나 예약어가 입력되어도 문법적인 의미로 작용하지 못한다.
    ➡️ 보안 향상

  • PreparedState를 사용하면 구문 분석(parse)의 결과를 캐싱해서 과정을 생략할 수 있으므로 성능이 향상된다.

💡 Statement VS PreparedStatment


✔️ 캐시(cache)사용여부에 따라 이 둘의 큰 차이점이 있다.

❗️ 성능 | 보안

  • Statement를 사용하면 매번 쿼리를 수행할 때마다 4단계를 거치게 되고(계속적으로 단계를 거치면서 수행)
    ➡️ 성능 저하
    ➡️ SQL Injection 공격에 취약: 보안 취약

  • PreparedStatement는 처음 한 번만 세 단계를 거친 후 캐시에 담아 재사용
    : 만약 동일한 쿼리를 반복적으로 수행한다면 PreparedStatment가 DB에 훨씬 적은 부하를 줌
    : SQL구문이 미리 컴파일 되어 사용자 입력값을 변수로 선언해 값을 대입하여 사용
    ➡️ 성능 향상
    ➡️ SQL Injection 공격 방어: 보안 향상

✏️ Statement

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

...

String sql = "SELECT * FROM MEMBER WHERE ID = '" + param_id + "' AND PW = '" + param_ passwd + "'";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
  • 사용자 입력값인 아이디와 패스워드 파라미터인 param_id, param_passwd에 SQL Injection 공격이 가능하다.

✏️ Prepared Statement

String param_id = request.getParameter("id");
String param_passwd = request.getParameter("passwd");
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;String sql = "SELECT * FROM MEMBER WHERE ID = ? AND PW = ?";
pstmt.setString(1, param_id);
pstmt.setString(2, param_passwd);
rs = pstmt.executeQuery(sql);
  • SQL구문이 미리 컴파일 되어 있고 사용자 입력값을 받는 부분을 '?'로 바인딩 처리를 하여 setString 메서드를 통해 외부 입력값을 받기 때문에 SQL Injection 공격이 불가능하다.

Reference
: https://kpfis.or.kr/ko/major_biz/cyber_safety_oper/attack_info/security_news?articleSeq=2588

profile
Fill in my own colorful colors🎨

0개의 댓글