728x90
300x250

[PHP] PHP 5.6 - 시큐어 코딩하기(SQL Injection)

 

실제 작성한 코드를 통해서 소개한다.

외부의 사용자가 스크립트 언어를 삽입하여 SQL 문장으로 공격하는 문제 등이 존재할 수 있다.

 

이를 막는 방법에 대해서 소개한다.

 

대상: PHP Version 5.6.36

         (선택) mysqlnd 5.0.11-dev - 20120503 

 


1. SQL 문장 변형이 일어나기 쉬운 코드

 

          /*
          $query = 'SELECT password FROM board_' . $boardName . '_comment ' .
                    'where id = \'' . $comment->getID() . '\' ' .
                    'and password = \'' . $password . '\'';
         */ // SQL Injection 미점검  

 

그림 1-1. 문자열로 생성하는 SQL 문장

 

이런 코드로 프로그래밍을 작성하면 다음과 같은 일들이 생길 수 있다.

 

 SELECT password FROM board_{임의의 질의값}_comment where id = {랜덤아이디, 스크립트} and password = {랜덤비밀번호 대칭};

 

그림 1-2. SQL 문장으로 공격하기

 

예를 들어서 화면을 아래처럼 꾸몄다고 가정하자.

 

번호

{id}

 

글 제목

{subject}

 

조회수

{count}

 

 

 

 

 

 

 

 

그림 1-3. UI - View.php

 

예를 들면, 그림 1-3에서 {id}의 내용에 불법적인 스크립트 등을 삽입하여 공격할 수가 있다.

이러한 것을 예방하려면, 아래의 코드처럼 개선하면 좋을 것으로 보인다.

 


  public function isPasswordComment($boardName, $comment){
  
          $link = mysql_connect($this->conn->getHost(),
                                          $this->conn->getUser(),
                                          $this->conn->getPw()) or
                                          die('Could not connect' . mysql_error());
                       
          mysql_set_charset('utf8', $link);
  
          mysql_select_db($this->conn->getDBName()) or die('Could not select database');

          mysql_query("set session character_set_connection=utf8;");
          mysql_query("set session character_set_results=utf8;");
          mysql_query("set session character_set_client=utf8;");
   
          $password = $this->crypt->decrypt( $comment->getPassword() );

         

          /*
          $query = 'SELECT password FROM board_' . $boardName . '_comment ' .
                    'where id = \'' . $comment->getID() . '\' ' .
                    'and password = \'' . $password . '\'';
         */ // SQL Injection 미점검  
  
          $query = sprintf("SELECT password FROM board_%s_comment WHERE `id` = '%s' AND " .
                     "`password` = '%s'",
                    mysql_real_escape_string($boardName),
                    mysql_real_escape_string($comment->getID()),
                    mysql_real_escape_string($password));       // SQL Injection 점검

  
           $result = mysql_query($query, $link) or die('Query failed: ' . mysql_error());

 

           // DB Article
           $password = "";
           while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
                  $password = $row['password'];
           }
  
           // Free resultset
           mysql_free_result($result);
  
           // Closing connection
           mysql_close($link);
  
           if ( empty($password) )
               return false;
           else
               return $password;
  
 } 

 그림 1-4. 개선된 코드(SQL Injection)

 


2. 참고자료(Reference)

 

1. SQL Injection, PHP.NET, http://php.net/manual/en/security.database.sql-injection.php, Accessed by 2018-07-31

반응형

+ Recent posts