본문 바로가기
Lecture/JSP & Java

[본격 웹보안 Part 1.2] SQL Injection이란 ?

by cusmaker 2012. 9. 19.
반응형

안녕하세요 cocy입니다.

오늘은 대표적인 웹 10대 보안 취약점 중 하나인 SQL인젝션(SQL Injection) 에 대해 배워 보도록 하겠습니다.

SQL은 데이터베이스의 쿼리언어라는 것을 짐작하실테고,

injection의 뜻은 주입하다, 주사하다 정도의 뜻입니다.


이 의미는 바로 사용자가 데이터를 넣을 수 있도록 만든 필드에

악의적으로 sql쿼리를 망가뜨리거나 변조할 수 있는 구문을 삽입하여,

개발자가 원래 의도하지 않은 기능을 수행케 하거나, 데이터베이스를 조작하여 정보유출 등을 일으킬 수 있는 

웹 해킹 공격 유형입니다.


설명보단 직접 실습하면서 이해하도록 하겠습니다.

지난시간에 만든 로그인 화면을 띄워주시기 바랍니다.



정상적이라면 회원 가입시 넣은 아이디와 패스워드를 입력하고,

메세지와 함께 로그인후 리스트화면을 보여주고,

만약에 잘못 입력하였다면 쿼리로부터 결과값을 돌려받지 못해 

유저정보를 체크하는 구문에 걸려 index페이지로 다시 돌아오도록 구성을 하였는데요,


저희는 파라미터를 받은뒤 쿼리를 완성할때 스트링으로 묶어 완성시켰습니다. 그렇다면

여기서 id나 패스워드칸에 악의적으로 쿼리를 변조하는 구문을 넣으면 어떻게 될까요?

실행되는 쿼리를 확인하기위해 login.jsp의 쿼리부분 밑에 쿼리를 출력하는 구문을 만들어주고

id값에는 아무값이나 넣고,

pw값에 다음과같은 문자를 넣어봅시다.

asdf' or 1=1 --'


실행 후 콘솔창의 결과는 다음과 같습니다.


쿼리를 보게 되면 

where 절 이후 조건이 들어가게 되는데 

여기에 악의적으로 파라미터를 닫히도록 '(single quotation) 을 넣고

or 구문과 1=1 이라는 조건을 더해 주었습니다. 그리고 이후 닫히는 ' 를 위해 

sql에서의 주석처리 구문 (--) 을 넣어 무효화 시켰습니다.


이로서 결과적으로 쿼리는 1=1이라는 항상 참값인 조건이 or조건과 만나 무조건 데이터를 반환하도록 쿼리가 변조된 것입니다.




이 구문 이외에도 쿼리에 능통하면 

서브쿼리를 이용하여 데이터들을 지울 수도 있고, 

심지어 DBA로 권한이 설정되어있다면 데이터베이스를 마음대로 주무를 수 있게됩니다.


그럼 이 공격을 막기위해서 어떤 대비책을 세워야 할까요?

(이번 포스팅에서는 해킹의 유형을 알아보기위해 수정하는 구문을 넣지 않겠습니다.)


첫번째방법으론 쿼리에 ' 가 못들어가도록 제한해야 합니다.

하지만 그건 사용자의 자유도를 제한하는 처사이기때문에 

' 문자를 단순 문자로 인식하도록 하면 될 것 같습니다.

그러기 위해선 파라미터 유효성 검증을 통해 정상적인 스트링인지 판별하는 구문을

javascript와 jsp측에 양쪽다 추가를 해 주어야합니다.

일단 javascript에서 추가를 해준다면 이런식으로 할 수 있겟습니다.

<!-- index.jsp -->

<html>

<head>

<script>

function validateLogin(){

 var id = document.forms[0].id;

 var pw = document.forms[0].pw;

 if(id.value == "") {

  alert("id is null");

  id.focus();

  return false;

 }else if(id.value.indexOf("'") != -1){
      alert("you can't use single qutation!");
      id.value = "";
      id.focus();
      return false;
 }

 if(pw.value == "") {

  alert("pw is null");

  pw.focus();

      return false;

 }else if(pw.value.indexOf("'") != -1){
      alert("you can't use single qutation!");
      pw.value = "";
      pw.focus();
      return false;
 }

}

</script>

</head>

<body>

<form action="login.jsp" onsubmit="return validateLogin()" >

ID : <input type="text" name="id" /> <br/>

PW: <input type="password" name="pw" /> <br/>

<input type="submit" value="로그인" />

<input type="button" value="회원가입" onclick="location.href='enter.jsp';" />

</form>

</body>

</html>


두번째로는 로그인하는 쿼리에 변화를 줍니다.

단순 조건만으로 판단하여 결과를 반환하는것이 아니라,

이중 삼중쿼리를 이용하여 해당쿼리로 사용자의 정보를 얻지 못하도록 쿼리를 짜는 것입니다.

예를들어 id와 pw가 f인 유저가 있다고 가정하면

select

 *

 from 

member 

where

     user_id = (select user_id from member where user_id = 'f' and user_pw = 'f')

이런식으로 서브쿼리를 이용하여 회원정보를 가져오도록 작성하면 

쿼리는 에러가 나지만,

적어도 쿼리에서 회원정보를 반환 하진 않겠죠?


이것들이 답이라는 것이 아니라, 

현상황에서 할 수있는 극히 미미한 대비책 중 하나라는 것입니다.

이외에도 다른 방법도 생각해보시기바랍니다.


해킹은 어떤방식으로 들어올 지 모르기때문에 다각도로 생각하고 방어해야합니다.

다음시간에는 폼 변조 해킹유형에 대해 알아보고 폼변조 공격과 연계하여 sql injection을 해 보도록 하겠습니다.

이번 강좌에서는 해결책을 직접 코드로 보여드리지 않겠습니다.

스스로 한번 찾아 보시기바랍니다.