PHP & MySQL

06. PHP & MySQL 보안

drizzle0925 2021. 3. 26. 13:05
728x90

입력 공격 차단 (SQL Injection)

SQL 인젝션(SQL 삽입, SQL 주입으로도 불린다)은 코드 인젝션의 한 기법으로 클라이언트의 입력값을 조작하여 서버의 데이터베이스를 공격할 수 있는 공격방식을 말한다.

index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
$conn = mysqli_connect(
  'localhost',
  'root',
  '111111',
  'tutorials');
$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'])) {
  //mysqli_real_escape_string 함수이용
  $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>
cs

 

 

www.php.net/manual/ja/mysqli.real-escape-string.php

 

PHP: mysqli::real_escape_string - Manual

オブジェクト指向型 real_escape_string($city));$result = $mysqli->query($query);printf("Select returned %d rows.\n", $result->num_rows);/* このクエリは失敗します。なぜなら、$city をエスケープしていないからで

www.php.net

php에서 제공하는 함수로 MYSQL과 커넥션을할때 String을 Escape한 상태로 만들어준다.

 

create.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
$conn = mysqli_connect(
  'localhost',
  'root',
  '111111',
  'tutorials');
$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>
cs

 

 

process_create.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?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>';
}
?>
cs

출력 공격 차단(Cross Site Scripting)

사이트 간 스크립팅(또는 크로스 사이트 스크립팅, 영문 명칭 cross-site scripting, 영문 약어 XSS)은 웹 애플리케이션에서 많이 나타나는 취약점의 하나로 웹사이트 관리자가 아닌 이가 웹 페이지에 악성 스크립트를 삽입할 수 있는 취약점이다. 주로 여러 사용자가 보게 되는 전자 게시판에 악성 스크립트가 담긴 글을 올리는 형태로 이루어진다. 이 취약점은 웹 애플리케이션이 사용자로부터 입력 받은 값을 제대로 검사하지 않고 사용할 경우 나타난다. 이 취약점으로 해커가 사용자의 정보(쿠키, 세션 등)를 탈취하거나, 자동으로 비정상적인 기능을 수행하게 할 수 있다. 주로 다른 웹사이트와 정보를 교환하는 식으로 작동하므로 사이트 간 스크립팅이라고 한다.

 

index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
$conn = mysqli_connect(
  'localhost',
  'root',
  '111111',
  'tutorials');
$sql = "SELECT * FROM topic";
$result = mysqli_query($conn$sql);
$list = '';
while($row = mysqli_fetch_array($result)) {
  $escaped_title = htmlspecialchars($row['title']); // htmlspecialchars
  $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>
cs

 

www.php.net/manual/ja/function.htmlspecialchars.php

 

PHP: htmlspecialchars - Manual

if your goal is just to protect your page from Cross Site Scripting (XSS) attack, or just to show HTML tags on a web page (showing on the page, for example), then using htmlspecialchars() is good enough and better than using htmlentities().  A minor point

www.php.net

htmlspecialchars - 특수문자를 HTML 엔티티로 변환한다.


Entity

흔히 한국에서는 Entity로 데이터베이스 엔티티로 많이들 쓰이는데, 여기서 엔티티는 개체를 의미한다.

 

사람이 생각하는 개념이나 정보 단위와 같은 현실 세계의 대상체, 실세계에 존재하는 유형 혹은 무형 정보의 대상이며 서로 구별이 되는 하나하나의 대상을 의미한다.

728x90