생활코딩

Coding Everybody

PHP & MySQL 보안

토픽 생활코딩 > WEB > WEB2 - PHP > WEB3 - PHP & MySQL

수업소개

여기서는 PHP와 MySQL을 연동할 때 발생할 수 있는 보안적인 문제를 해결하고, 이를 완화하는 방법을 소개합니다. 

 

입력 공격의 차단

 

변경사항 보기

index.php

<?php
$conn = mysqli_connect(
  'localhost',
  'root',
  '111111',
  'opentutorials');
$sql = "SELECT * FROM topic";
$result = mysqli_query($conn, $sql);
$list = '';
while($row = mysqli_fetch_array($result)) {
  $list = $list."<li><a href=\"index.php?id={$row['id']}\">{$row['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'] = $row['title'];
  $article['description'] = $row['description'];
}
?>
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>WEB</title>
  </head>
  <body>
    <h1><a href="index.php">WEB</a></h1>
    <ol>
      <?=$list?>
    </ol>
    <a href="create.php">create</a>
    <h2><?=$article['title']?></h2>
    <?=$article['description']?>
  </body>
</html>

create.php

<?php
$conn = mysqli_connect(
  'localhost',
  'root',
  '111111',
  'opentutorials');
$sql = "SELECT * FROM topic";
$result = mysqli_query($conn, $sql);
$list = '';
while($row = mysqli_fetch_array($result)) {
  $list = $list."<li><a href=\"index.php?id={$row['id']}\">{$row['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'] = $row['title'];
  $article['description'] = $row['description'];
}
?>
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>WEB</title>
  </head>
  <body>
    <h1><a href="index.php">WEB</a></h1>
    <ol>
      <?=$list?>
    </ol>
    <form action="process_create.php" method="POST">
      <p><input type="text" name="title" placeholder="title"></p>
      <p><textarea name="description" placeholder="description"></textarea></p>
      <p><input type="submit"></p>
    </form>
  </body>
</html>

process_create.php

<?php
$conn = mysqli_connect(
  'localhost',
  'root',
  '111111',
  'opentutorials');
$filtered = array(
  'title'=>mysqli_real_escape_string($conn, $_POST['title']),
  'description'=>mysqli_real_escape_string($conn, $_POST['description'])
);
$sql = "
  INSERT INTO topic
    (title, description, created)
    VALUES(
        '{$filtered['title']}',
        '{$filtered['description']}',
        NOW()
    )
";
$result = mysqli_query($conn, $sql);
if($result === false){
  echo '저장하는 과정에서 문제가 생겼습니다. 관리자에게 문의해주세요';
  error_log(mysqli_error($conn));
} else {
  echo '성공했습니다. <a href="index.php">돌아가기</a>';
}
?>

 

SQL 주입(injection)의 차단

 

 

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

 

변경사항

index.php


<?php
$conn = mysqli_connect(
  'localhost',
  'root',
  '111111',
  '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']);
}
?>
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>WEB</title>
  </head>
  <body>
    <h1><a href="index.php">WEB</a></h1>
    <ol>
      <?=$list?>
    </ol>
    <a href="create.php">create</a>
    <h2><?=$article['title']?></h2>
    <?=$article['description']?>
  </body>
</html>

 

 

댓글

댓글 본문
  1. 23.12.19 보안.
  2. pmxsg
    2022.01.22
  3. chimhyangmoo
    21.06.29
  4. jwoh
    21-04-26
  5. jeisyoon
    2021.04.17 PHP & MySQL 보안 - OK
  6. hanel_
    21.3.2
  7. siver
    완료
  8. クレヨンしんちゃん
    ㅇㄹ
  9. jaehyunlee
    06/14 고3 완료
  10. 강강
    bitnami를 windows 10에 설치하고 실습을 진행하고 있는데
    sql injection 구문이 실행되지 않습니다. 주석을 '--'로 넣어서 안되는가 보다고 생각하고 '#'을 넣어서 시도 했는데 error 만 발생하고 sql injection이 실행되지 않습니다.

    하지만 정상적인 입력을 정상적으로 잘 처리해서 php코드가 정상적인것 같아서 mysql이나 wamp가 자체적으로 방어하는건지 궁금합니다.

    자세한 사양과 로그는 아래와 같습니다.
    ㅇBitnami 버전 : wampstack-7.3.7
    ㅇ 로그 내역
    [Sun Mar 15 21:43:08.713049 2020] [php7:notice] [pid 16560:tid 1176] [client ::1:28483] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*',\r\n\t\tNOW()\r\n\t)' at line 4, referer: http://localhost......php
    [Sun Mar 15 21:46:43.443891 2020] [php7:notice] [pid 16560:tid 1212] [client ::1:28571] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '--',\r\n\t\tNOW()\r\n\t)' at line 4, referer: http://localhost......php
    [Sun Mar 15 21:46:59.515909 2020] [php7:notice] [pid 16560:tid 1176] [client ::1:28575] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOW()\r\n\t)' at line 5, referer: http://localhost......php
  11. Giri
    감사합니다.
  12. 허공
    190508 감사합니다.
  13. 해요
    스크립트 공격 태스트 한다고 해봤는데
    Chrome이 이 페이지에서 비정상적인 코드를 감지했으며 개인정보(예: 비밀번호, 전화번호, 신용카드) 보호를 위해 차단했습니다.
    이렇게 나오는게 정상인거죠??
  14. heesang
    좋은 강의 정말 감사드립니다!
  15. maker
    감사합니다
  16. bird
    mysqli_real_escape_string을 적용해놓고 글을 쓰면 리스트에 빈화면으로 나오는데 원래 이런건가요?
  17. 윤민
    하 어렵다....
  18. 제갈량
    보안은 항상 어려운 이야기 인거 같아요.
    그래도 잘 봤습니다.