easycode

SQL Injection 설명과 예방법(Mybatis&JPA) 본문

CS

SQL Injection 설명과 예방법(Mybatis&JPA)

ez() 2024. 1. 16. 00:14

 


면접 준비를 하며 공부했던 CS 지식 중 SQL Injection에 대해 공부한 걸 간단하게 기록해보려 합니다. 제게 필요한 내용만 요약한 거라 좀더 자세한 내용과 이해를 원하신다면 아래에 있는 참고사이트를 봐 주세요! 누군가에게 이 글이 도움이 되기를 바랍니다.

 

 


SQL Injection이란?

공격자가 동적 쿼리를 생성하여 DB 정보를 열람하거나 마음대로 조작하는 것을 뜻합니다.

 

 

 

SQL Injection 방어 (Mybatis) : #{ } 사용하기!

파라미터를 넣을 때 #{ }를 사용하면 된다. #{ }이 내부적으로 PrepareStatement를 사용하기 때문에 쿼리와 입력값을 분리해 줘 SQL Injection 공격에 안전하다 (문자열 형태로 들어와서 파라미터 형태가 됩니다)

 

 

 

SQL Injection 방어 (JPA) : 기본 메서드에서 SQL Injection 방어 지원

기본적으로 대응되긴 하나, 입력값을 넣을 때 파라미터 바인딩을 사용하자!
JPA는 기본 메서드에서 PrepareStatement를 사용하여 SQL Injection을 방어한다. 기본적으로 제공하는 API 내에 Parameter Binding을 이용하고 있어 SQL Injection에 대응할 수 있다.
그러나 JPA query를 만들어서 사용할 때도 입력값을 바로 쿼리에 넣게되면 SQL injection에 취약하므로, 이때도 파라미터 바인딩을 사용해야 한다.

 

 

 

 

Prepare Statement를 이용한 SQL Injection 방어

  • Prepare Statement는 DB 스펙이다. 즉, DB에서 미리 준비된 구문을 설정하고 실행 계획까지 다 세워 놓은 후, 여기에 파라미터만 입력받아 실행한다.
  • 즉, String을 JAVA단에서 들고 있다가 단순히 치환하는 게 아닌 DB에 미리 실행계획을 생성해두고 파라미터 값만 받는다는 뜻입니다.
select * from user where login_id = {loginId}

 

  • 위와 같은 쿼리문이 있다고 할 때, DB는 미리 실행 계획을 만들고 {loginId} 라는 파라미터만 기다리고 있다. 즉, DB는 들어 올 Input 값을 String형으로 기대하고 있는 것이다.
  • Prepared Statement 는 DB 입장에서 미리 실행계획을 짜놓은 상태에서 대기하기 때문에 효율도 좋다.

 

 

 

동적쿼리의 SQL Injection

  • 동적쿼리를 만들더라도 확정쿼리에 파라미터 바인딩을 추천한다. 변수를 대입받아 그대로 집어넣는 것은 각종 SQL Injection 대상이 되니 주의하자!

 

 


참고사이트

1. Spring 에서 SQL Injection 방어 그리고 원리 (feat. Prepared Statement, JPA, MyBatis) : https://developer-ping9.tistory.com/545

 

[보안] Spring 에서 SQL Injection 방어 그리고 원리 (feat. Prepared Statement, JPA, MyBatis)

서문 회사 서비스에 AWS WAF 를 전역적으로 설정하면서 소량의 보안지식을 쌓을 수 있었다. 그러다 문득 Spring Application 은 SQL Injection 을 제대로 방어하고 있을까? 라는 궁금증이 생겨났다. Spring 에

developer-ping9.tistory.com