면접대비

SQL Injection 이야기(MyBatis, JPA)

코딩하는흑구 2021. 4. 10. 01:18

안녕하세요.

 

SQL Injection에 대해서 공부해본 내용을 공유하고자 합니다.

 

대부분 웹 해킹에 대해서는 보안의 중요성이나 방지방법만 파악하고 여러가지 유형에 대해서는 간과한 것 같아서 그 부분도 함께 스터디를 해봤습니다.

 

깊진 않지만 어디가서 말 못할 정도의 내용은 아닐 수 있도록 정리해보겠습니다.

 


 

SQL 인젝션이란??

SQL 인젝션은 백엔드 데이터베이스 단에 저장된 중요한 정보들에 접근하기위해 SQL 쿼리문을 조작하는 공격중 하나이다. 이 중요한 정보들에는 회사의 민감한 정보, 개인 고객 정보 등이 있을 수 있다. 이 공격의 영향으로 회사에는 막대한 피해를 입을수 있습니다. SQL 인젝션 공격에 성공한다면 접근할 수 없는 고객 목록을 확인하거나 데이터베이스 스키마를 삭제하거나 내용을 수정하거나 웹에서의 행위 심지어는 운영 데이터베이스에 접근해서 회사의 운영에 막대한 피해를 입게할 수 있습니다. 또는 공격자가 지속적 혹은 장기간에 걸쳐 눈에 띄지 않게 회사 시스템을 공격하여 피해를 끼칠 수 있습니다. 

이미 많은 유명한 회사들이 SQL 인젝션 공격을 당했고 그 명성에 금이간 경험이 많습니다. SQL 인젝션은 어플리케이션 내에서 신뢰할 수 없는 데이터 양식을 사용할 때 발생할 수 있게 됩니다. (신뢰할수 없는 데이터는 사용자의 입력인 것 같습니다.)

 

SQL 인젝션의 예시들

  • 히든 데이터 검색(Retrieving hidden data) : 숨겨진 데이터를 검색하기 위해 SQL 문을 수정한다.
  • 어플리케이션 내 로직 변경 : 어플리케이션 실행 로직을 방해하기 위해 SQL 문을 수정한다.
  • Blind SQL 인젝션 : 사용자에 의해 수행된 쿼리의 결과가 어플리케이션의 응답으로 반환되지 않는다.
  • 데이터베이스 검사 : 데이터베이스의 정보(버전, 구조)를 얻기 위해 일부로 에러를 발생시킨다.
  • union 공격 : 다양한 데이터베이스 테이블에서 정보를 검색할 수 있다.

위 예를 들어서 간단히 설명을 첨언하자면,

 

SQL 주입하여 서버의 에러메시지를 유발시켜 특정 데이터베이스에서만 존재하는 에러메시지를 유발하여 서버의 DB 종류를 파악할 수 있게 할 수 있고, Union 연산자를 활용하여 특정 쿼리문에 컬럼의 갯수가 몇개가 존재하는지와 같은 부분을 union 연산을 주입하여 확인할 수 있게 한다.

 

이 부분에 대한 내용은 생각보다 깊어서 추후에 따로 정리해보려 한다.

 


 

현재 대한민국 Java Spring 백엔드 개발자들이 가장 많이 사용하는 Sql Mapper와 ORM인 MyBatis와 JPA에서는 이러한 부분이 해결되었을까??

 

Mybatis

MyBatis에서는 SQL Mapper에서 ${} 문법과 #{} 문법을 지원하고 있는데, ${} 문법에서 Sql Injection의 위험성을 가지게 된다. #{} 문법은 Parameter Binding을 활용하여 여러 Escape를 통해 파라미터를 생성하고 parameter를 sql에 binding 하게 해준다. 하지만 ${} 문법은 SQL 쿼리문에 직접 꽂기 때문에(Query String) 위와 같은 SQL Injection 공격이 가능해진다.

이에 대한 내용을 포스팅한 적이 있으니 MyBatis를 사용하시는 분들은 참고하시기 바랍니다!

sas-study.tistory.com/96

Spring mybatis에서 #{ }문법과 ${ }문법의 차이점(feat. SQL Injection)

안녕하세요. 오늘 공유할 내용은 Spring mybatis에서 사용하는 #{} 문법과 ${} 문법의 차이와 ${}문법을 사용했을때 발생할 수 있는 SQL Injection이라는 해킹 방법에 대하여 내용을 공유하고자 합니다. 먼

sas-study.tistory.com

 

JPA

Spring Data JPA에서 제공하는 API(save(), saveAll() 등의)를 활용하게 된다면 SQL 인젝션에 대한 고민은 거의 하지 않게될 것이다. 내부적으로 이미 Parameter Binding을 활용하고 있다고 공식적으로 이야기하고 있기 때문인데.. 하지만 위험한 길은 있기 마련이다..

예컨데 SQL 쿼리 스트링을 직접 짜서 entityManager에 전달한다던가 이런식의 JPA 활용은 다소 위험을 유발할 수 있다.

 


 

SQL Injection에서의 대부분의 해답은 Parameter Binding이라는 부분으로 해소할 수 있습니다. 하지만 적어도 Parameter Binding을 사용하기 전에 어떠한 루트로 공격이 들어올지 예상할 수 있는 정도로는 알아야 한다고 생각합니다.

 

SQL 인젝션에 대해서 알아보았지만 생각보다 내용이 상당히 깊었고 일단은 수박 겉핥기라는 정도로밖에 생각되지 않는 내용이긴 합니다... ㅠ 하지만 어느정도 개요는 제시했다고 생각하고 이 정도깊이는 충분히 받아들일 수 있다는 분들은 아래의 참조를 확인하시어 키워드들을 알아가 보시면 좀더 SQL Injection에 대한 공부가 될거라고 생각합니다. 

 

 

 

참조