MySQL09 SQL 삽입공격 & SQL 실행과정

업데이트:
2 분 소요

비트캠프 서초본원 엄진영 강사님의 수업을 듣고 정리했습니다.


1. SQL 삽입 공격

(1) SQL 삽입 공격

  • 사용자의 입력 값으로 SQL 문을 만들 때 가능한 공격 방법이다.
  • 값을 입력할 때 SQL 문에 영향을 끼치는 SQL 코드를 함께 삽입하는 방법이다.

SQL 삽입 공격 예

  • SQL 문: select * from user where username='아이디' and password='암호'
    • 아이디: hongkildong
    • 암호: 'ok' or 1=1 --
  • 입력 값이 포함된 최종 SQL 문
    • select * from user where username='hongkildong' and password='ok' or 1=1 --'
    • 1=1 조건은 무조건 참이므로 username 과 password가 일치하지 않더라도 상관없이 결과는 true 이다.
    • -- 은 줄 끝까지 주석으로 취급하기 때문에 SQL 문의 끝에 있던 작은 따옴표를 제거하는 효과가 있다.

해결 방법

  • Statement 대신에 PreparedStatement 를 사용하면 된다.

(2) Statement vs PreparedStatement

SQL 삽입 공격

  • Statement : 가능
  • PreparedStatement : 불가능

바이너리 컬럼 값 넣기

  • Statement : 불가능
  • PreparedStatement : 가능

코드의 간결함

  • Statement : 가독성이 떨어진다. String.format()으로 개선할 수 있다.
  • PreparedStatement : in-parameter 문법으로 SQL 문과 값을 분리하기 때문에 가독성이 좋다.

실행 속도

  • Statement
    • SQL을 실행할 때 마다 DBMS는 매번 SQL 구문 분석 → 최적화 → 실행 과정을 거친다.
  • PreparedStatement
    • 처음 SQL을 실행할 때 딱 한 번 SQL 구문 분석 → 최적화 → 실행 과정을 거친다.
    • 이 이후에는 내부 SQL 공유 풀에 보관된 최적화된 실행 계획을 바로 실행한다. (hard parsing까지 되어있다.)
    • 따라서 SQL을 준비한 후 반복하여 실행하는 경우에는 Statement 보다 빠르다.

표로 정리

  Statement PreparedStatement
SQL 삽입 공격 가능 불가능
바이너리 컬럼 값 넣기 불가능 가능
코드의 간결함 가독성이 떨어진다. 가독성이 좋다.
실행 속도 느리다. 빠르다.

2. SQL 실행 과정(오라클 DBMS의 예)

(1) SQL 구분 분석(Parsing)

문법의 유효성 검사(Syntax Check)

  • 문법의 규칙을 준수하는지 검사한다.
  • 예) select * form pms_board

    form 은 잘못된 SQL 문법이다.

SQL 문의 의미 검사(Semantic Check)

  • SQL 문에서 지정하는 컬럼이나 테이블, 뷰 등이 유효한지 검사한다.
  • 예) select * from pms_okok

    pms_okok 테이블이 없다면, semantic 오류이다.

SQL 공유 풀 검사(Shared Pool Check)

  • 공유 풀은 SQL 문에 대해 생성된 실행 계획(execution plan) 등을 보관한다.
  • 먼저 SQL 문에 대해 해시(hash) 연산을 수행하여 SQL ID를 생성한다.
  • 공유 풀에 저장된 값 중에서 SQL ID와 일치하는 값이 있는지 조사한다.
    • 만약 있다면, 즉시 해당 값을 꺼내 실행 계획에 따라 SQL 문을 실행한다.
    • 없다면, 하드 파싱(hard parsing)이라는 과정을 수행한다.

(2) 하드 파싱

SQL 최적화(Optimization)

  • SQL 문을 가장 효율적으로 실행할 수 있게 재구성한다.
  • 각 문장 별로 실행 계획(execution plan)이라는 명령 코드를 생성한다.
  • 여러 개의 실행 계획을 검토한 후 실행 비용을 계산하여 최적의 실행 계획을 생성한다.

SQL 컴파일(Row Source Generation)

  • 최적화 단계에서 생성된 실행 계획을 입력으로 받는다.
  • 각 실행 단계 별로 결과 데이터(result set)를 리턴할 바이너리 명령을 생성한다.
  • 이 바이너리 명령을 Row Source 라고 부른다.
  • Row Source는 테이블이나 뷰, 조인 또는 그룹 연산을 가리킨다.
  • Row Source Generator는 실행 순서에 따라 Row Source Tree를 생성한다.

(3) SQL 실행

  • SQL 엔진은 Row Source Tree**에 따라가면서 *Row Source 바이너리 명령을 실행한다.
  • Row Source 바이너리 명령은 테이블이나 뷰, 조인 또는 그룹 연산 결과를 생성한다.
  • 최종 실행 결과는 애플리케이션에게 리턴할 결과 데이터(Result Set)이다.

SQL 실행과정

태그:

카테고리:

업데이트: