power-girl0-0

[ PHP & MySQL ] PHP & MySQL 보안 본문

언어/PHP

[ PHP & MySQL ] PHP & MySQL 보안

power-girl0-0 2021. 3. 29. 13:51
728x90

생활코딩 PHP & MySQL을 참고하여 공부하였습니다.

스스로 공부한 것을 정리하고 복습하기 위한 목적으로 작성하였습니다.

( 출처 :  https://opentutorials.org/course/743inf.run/pBzy opentutorials.org/course/3167)


 입력 공격의 차단 

보안에 있어서 주요한 사고는 크게 두가지이다.

 

1. 들어오는 정보에서 문제가 있는 정보를 막아낸 것

2. 문제가 있는 정보가 이미 있는 상태에서, 그 정보가 사용자들에게 노출될 때 문제 있는 정보를 차단하는 것 

 

즉, 입력과 출력에서 보안 사고가 일어난다.

 

사용자가 입력한 정보에서 문제가 될만한 정보를 차단하는 행위를 "filtering"이라고 하며,

저장되어 있는 정보를 사용자에게 노출할 때 발생할 수 있는 행위를 "excaping"이라고 한다.

 


보안이 취약한 경우, 사용자가 sql문을 입력하게 되면 쿼리문이 실행되는 부분에서 문제점이 발생한다.

 

이를 해결하기 위해서는 php와 mysqli에서 지원하는 api를 사용하면 된다.

이는 mysqli_real_escape_string( )함수이다.

 

해당 명령을 사용하게 되면, 인자로 들어온 데이터 중에서 sql주입 공격과 관련된 특수기호들을 문자로 바꿔버리는 함수이다.

 

데이터베이스에 값을 입력하거나 정보를 출력하는 부분에서 사용된다.

아래는 앞에서 실습한 코드 중, mysqli_real_escape_string( ) 함수를 작성하여 보안한 소스코드이다.

if(isset($_GET['id'])) {
  $filtered_id = mysqli_real_escape_string($conn, $_GET['id']);
  $sql = "SELECT * FROM topic WHERE id={$filtered_id}";
  $result = mysqli_query($conn, $sql);
  $row = mysqli_fetch_array($result);
  $article['title'] = $row['title'];
  $article['description'] = $row['description'];
}

만약 이를 보안하지 않았을 경우, 사용자에 의해 데이터베이스의 정보가 노출될 가능성이 크기 때문에 꼭 보안해줘야 하는 부분임을 명확히 알아야 한다.


 출력 공격 (Cross site scripting )의 차단 

 사용자가 데이터를 입력하면서, 악의적인 목적으로 자바스크립트 코드를 주입할 수 있다.

실습을 통해 자세히 알아보자.

 

아래와 같이, description에

자바스크립트 명령어 중에서 사용자를 다른 사이트로 보내는 명령어를 작성해보았다.

작성후, 제출을 클릭한 결과 attack이라는 메뉴가 하나 더 생성된다.

 

이를 클릭시, 설정했던 naver사이트로 이동하는 것을 확인할 수 있다.


해당 기법은 Cross site scripting이라는 공격 기법이다.

 

이러한 공격 기법을 이용해서 악의적인 사이트로 들어가게 하여, 사용자의 권한을 빼앗거나 정보 유출도 가능하다.

 

그렇다면, 어떻게 방어해야 될까??!!

html에서는 <script>를  &lt;script&gt; 형식으로 표현하여, <>가 입력될시 문자로 출력하게 해준다.

 

이와 같이 실행해주는 함수가 php에서는 htmlspecialchars( ) 함수이며, 이를 이용하여 필터링이 가능하다.


자 그럼 이전 소스코드에서 적용해보자.

참고로 코드에서 id값은 데이터베이스에서 자동으로 증가하는 것이기 때문에 필터링해줄 필요가 없다.

따라서, 사용자에 의해서 출력될만한 부분만 필터링해주면 된다. 코드는 아래와 같다.

<?php
    $conn = mysqli_connect(
      'localhost',
      'root',
      'db 비밀번호',
      'opentutorials');
    $sql = "SELECT * FROM topic";
    $result = mysqli_query($conn, $sql);
    $list = '';

    while($row = mysqli_fetch_array($result)) {
      $escaped_title = htmlspecialchars($row['title']);
      $list = $list."<li><a href=\"index.php?id={$row['id']}\">{$escaped_title}</a></li>";
    }

    $article = array(
      'title'=>'Welcome',
      'description'=>'Hello, web'
    );

    if(isset($_GET['id'])) {
      $filtered_id = mysqli_real_escape_string($conn, $_GET['id']);
      $sql = "SELECT * FROM topic WHERE id={$filtered_id}";
      $result = mysqli_query($conn, $sql);
      $row = mysqli_fetch_array($result);
      $article['title'] = htmlspecialchars($row['title']);
      $article['description'] = htmlspecialchars($row['description']);
    }

?>

 

 

728x90

'언어 > PHP' 카테고리의 다른 글

[ PHP & MySQL ] 글 삭제  (0) 2021.03.29
[ PHP & MySQL ] 글 수정  (0) 2021.03.29
[ PHP & MySQL ] 글 읽기  (0) 2021.03.29
[ PHP & MySQL ] SELECT  (0) 2021.03.29
[ PHP & MySQL ] 글 생성  (0) 2021.03.28
Comments