잡다한 IT관련 지식

SQL Injection 공격 대응방안:Prepared Statement를 사용하는 이유

웹하는빡통 2019. 10. 23. 17:08

1. Prepared Statement 사용하는 이유를 설명하고자 한다. 

SELECT 문 실행 과정


웹 상에서 입력한 쿼리는 DBMS 내부적으로 4가지 과정(parse,bind,execute,fetch)를 거쳐 결과를 출력한다.
특히 쿼리의 문법을 검사하기 위해 가장 먼저 parse과정을 거치게 되는데,
입력한 쿼리의 결과를 다음과 같이 파싱하여 트리를 생성한다.

 

statement와 Prepared Statement의 차이(파싱과 바인딩)

일반적인 Statement를 사용하여 SELECT 쿼리를 입력했을 때에는 매번 pares부터 fetch까지 모든 과정을 수행한다.
Prepared Statement를 사용하는 경우 효율을 높이기 위해 pare과정을 최초 1번만 수행하고 이후는 생력 할 수 있다.
Parse 과정을 모두 거친 후에 생성된 결과는 메모리 어딘가에 저장 해두고 필요할 때마다 사용한다.
반복적으로 트리를 사용하기 위해서 자주 변경되는 부분을 변수로 선언하고 매번 다룬 값을 대입(바인딩)하여 사용한다.

바인딩 데이터는 SQL문법이 아닌 내부의 인터프리터나 컴파일 언어로 처리하기 때문에 문법적인 의미를 가질 수 없다

따라서 바인딩 변수에 SQL공격 쿼리를 입력할지라도 의미있는 쿼리로 동작하지 않는 이유이다.

그래서 Prepared Statement에서 바인딩 변수를 사용하였을 때 쿼리의 문법 처리과정이 미리 선 수행되기 때문에 바인딩 데이터는 SQL문법적인 의미를 가질 수 없다. 그래서 Prepared Statement를 사용하면 SQL 인젝션 공격에 안전하게 구현 할 수 있는 이유이다. 

 

출처: http://blog.skinfosec.com/220482240245

 

바인딩 변수?:

 

PL/SQL 외부에서도 사용할 수 있는 변수로 쉽게 말하면 입력 내용을 넣고 SQL로부터 출력 내용을 받아내는 방법으로, " 이 부분에 들어갈 정확한 값은 이후에 알려줄테니, 일단 내가 값을 넣었을 때 어떻게 실행할 것인지에 대해서 계획만 세워둬라 "는 명령을 오라클에 내리는 것이다.

 

EX) 1번째 쿼리: select * from emp where ename = 'KING'; 바인딩 변수 선언X
      2 번째 쿼리: select * from emp where ename = :bv; 바인딩 변수 선언

 

두번째 쿼리가 바인드 변수를 사용한 쿼리로서, 보다 일반적이고, 재사용할 수 있는 형태이다.
(: = 는 대입(할당 변수)이고, = :는 비교(바인드 변수 -  ":"가 붙은 변수)이다.

 

파싱?:

파싱은 어떤 페이지(문서, html 등)에서 내가 원하는 데이터를 특정 패턴이나 순서로 추출해 가공하는 것을 말한다. 먼저 파서는 컴파일의 일부로서 원시 프로그램의 명령문이나 온라인 명령문, HTML 문서 등에서 MArkup Tag 등을 입력으로 받아들여서 구문을 해석할 수 있는 단위와 여러 부분으로 분할해주는 역할을 한다. 이러한 파서(parser) 역할을 하는 컴퓨터가 구문 트리(parse tree)로 재구성하는 구문 분석 과정을 뜻한다. 파싱 과정에서는 부호에 불과한 일련의 문자열이 기계어로 번역되고 의미있는 단위가 된다. 그 종류는 상향식 파싱(bottom-up parsing)과 하향식