2023.01.31 - [Secure Coding/SQL Injection] - [ Secure Coding ] SQL Injection (SQL 인젝션) - Java
이전 글에서 SQL Injection에 대해서 포스팅 했었는데, 이번 글에선 PreparetStatement와 Statement의 차이점과 실제 예시들을 다루고자한다.
PreparedStatement vs Statement
1. 차이점
PreparedStatement와 Statement의 가장 큰 차이점은 캐시(cache) 사용 여부이다.
Sql 쿼리문을 실행할 땐 아래와 같은 과정을 거친다.
- Query문 분석
- 컴파일
- 실행
Statement를 사용하면 매번 쿼리를 수행할 때마다 1~3번 과정을 거치며,
PreparedStatment는 처음 한 번만 세 단계를 거친 후 캐시에 담아 재사용한다.
2. Statement 동작 방식 (코드)
아래는 Statement를 사용하는 코드이다. (예시로 작성 된 코드이므로 빨간 줄은 무시해도 된다.)
Statement는 위의 코드처럼 String으로 Sql 쿼리를 한 번에 생성하고, 쿼리를 실행(executeQuery())할 때 파라미터로 전송한다.
Sql 쿼리문이 어떤 동작을 하는지 파악하기 쉽지만, 매번 컴파일하기 때문에 성능에 부담이 된다.
3. PreparedStatement 동작 방식 (코드)
PreparedStatement의 경우는 아래와 같다. (tableName과 idFieldName은 SQL Injection과 관계 없는 부분이니 ? 부분만 보면 된다.)
Statment와 다르게 ? 부분에만 변화를 주며 SQL을 수행한다. (바인딩)
사용자가 입력한 변수가 들어갈 공간을 ?로 지정해두고, 사용자의 입력을 ? 위치에다가 대입하는 방식인 것
입력 값을 ?에 바인딩하는 과정에서 set 메소드를 사용하는데 이 과정에서 문법 처리를 수행한다.
쿼리문을 생성하기 전에 먼저 문법 처리를 수행하기 때문에 사용자가 입력한 값은 문법적인 의미를 가질 수 없다.
이러한 동작 과정 때문에 쿼리문의 형태가 변하지 않아 캐시에 담아 재사용할 수 있는 것이다.
PreparedStatment, Statement 실제 예시
1. Statment를 사용한 경우
내 프로젝트에선 PreparedStatment를 사용했기 때문에 친구 프로젝트를 빌려왔다.
Statement를 사용했기 때문에 출력 창에 기존에 저장되어 있던 id와 password가 출력된 것을 볼 수 있다.
2. PreparedStatement를 사용한 경우
PreparedStatement를 사용했기 때문에 사용자의 입력 값이 문법적인 의미를 가지지 않아서 null이 나온 것을 볼 수 있다.
SQL Injection 같은 부분은 학부생 수준의 프로젝트에서 특히 많이 놓칠 수 있는 부분인 것 같다.
간단하게 방어를 할 수 있기 때문에 프로젝트에 직접 적용해보면 좋을 듯하다.
'Secure Coding > SQL Injection' 카테고리의 다른 글
[ Secure Coding ] SQL Injection (SQL 인젝션) - Java (0) | 2023.01.31 |
---|