웹 애플리케이션 만들기

보안

보안1

보안2

php/5.php

사용자가 입력한 script 태그를 무력화시키는 방법. (참고 : htmlspecialchars)

<html>
  <head>
    <title></title>
  </head>
  <body>
    <?php
       echo htmlspecialchars('<script>alert(1);</script>');
    ?>
  </body>
</html>

index.php

<?php
$conn = mysqli_connect("localhost", "root", 111111);
mysqli_select_db($conn, "opentutorials");
$result = mysqli_query($conn, "SELECT * FROM topic");
?>
<!DOCTYPE html>
<html>
<head>
     <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="http://localhost/style.css">
</head>
<body id="target">
	<header>
    <img src="https://s3.ap-northeast-2.amazonaws.com/opentutorials-user-file/course/94.png" alt="생활코딩">
		<h1><a href="http://localhost/index.php">JavaScript</a></h1>
  </header>
	<nav>
		<ol>
    <?php
    while( $row = mysqli_fetch_assoc($result)){
      echo '<li><a href="http://localhost/index.php?id='.$row['id'].'">'.htmlspecialchars($row['title']).'</a></li>'."\n";
    }
    ?>
		</ ol>
	</nav>
  <div id="control">
    <input type="button" value="white" onclick="document.getElementById('target').className='white'"/>
    <input type="button" value="black" onclick="document.getElementById('target').className='black'" />
    <a href="http://localhost/write.php">쓰기</a>
  </div>
  <article>
  <?php
  if(empty($_GET['id']) === false ) {
      $sql = "SELECT topic.id,title,name,description FROM topic LEFT JOIN user ON topic.author = user.id WHERE topic.id=".$_GET['id'];
      $result = mysqli_query($conn, $sql);
      $row = mysqli_fetch_assoc($result);
      echo '<h2>'.htmlspecialchars($row['title']).'</h2>';
      echo '<p>'.htmlspecialchars($row['name']).'</p>';
      echo strip_tags($row['description'], '<a><h1><h2><h3><h4><h5><ul><ol><li>');
  }
  ?>
  </article>
</body>
</html>

보안3

/phpjs/14.php

<?php
$conn = mysqli_connect("localhost", "root", 111111);
mysqli_select_db($conn, "opentutorials");
$name = mysqli_real_escape_string($conn, $_GET['name']);
$password = mysqli_real_escape_string($conn, $_GET['password']);
$sql = "SELECT * FROM user WHERE name='".$name."' AND password='".$password."'";
echo $sql;
$result = mysqli_query($conn, $sql);
?>
<!DOCTYPE html>
<html>
<head>
     <meta charset="utf-8">
</head>
<body>
  <?php
  if($result->num_rows == "0"){
    echo "뉘신지?";
  } else {
    echo "안녕하세요. 주인님";
  }
  ?>
</body>
</html>

process.php

원래는 process.php 파일에도 보안을 적용해야 합니다. 하지만 우리수업에서는 수업 시간을 줄이기 위해서 생략합니다. 참고로 아래와 같이 process.php  개선할 수 있습니다. 아래 파일을 그대로 적용해주세요.
<?php
$conn = mysqli_connect("localhost", "root", 111111);
mysqli_select_db($conn, "opentutorials");

$title = mysqli_real_escape_string($conn, $_POST['title']);
$author = mysqli_real_escape_string($conn, $_POST['author']);
$description = mysqli_real_escape_string($conn, $_POST['description']);

$sql = "SELECT * FROM user WHERE name='".$author."'";
$result  = mysqli_query($conn, $sql);
if($result->num_rows == 0){
  $sql = "INSERT INTO user (name, password) VALUES('".$author."', '111111')";
  mysqli_query($conn, $sql);
  $user_id = mysqli_insert_id($conn);
} else {
  $row = mysqli_fetch_assoc($result);
  $user_id = $row['id'];
}
$sql = "INSERT INTO topic (title,description,author,created) VALUES('".$title."', '".$description."', '".$user_id."', now())";
$result = mysqli_query($conn, $sql);
header('Location: http://localhost/index.php');
?>

소스코드

github

참고

보안의 중요한 주제인 암호화에 대해서 궁금하신 분은 아래 수업을 참고해주세요.

암호화를 이용한 보편적이지 않은 코딩

댓글

댓글 본문
작성자
비밀번호
  1. hanulsso
    반복학습이 필요한 수업이네요
    여러번 복습하겠습니다.
    저런게 보안이었군요 재밌습니다 어렵지만
  2. 이근환
    2017-12-12 수강 15일차

    수강완료하였습니다.

    htmlspecialchars와 strip tags, mysqli_real_escape_string을 배우고

    또 보안에 대해서 생각해보는 시간을 가지게 되어서 뜻 깊은 강의였습니다!
  3. jkedu714@gmail.com
    와.... 난이도가 급 올라가는 듯한 느낌이네요 ㅠㅠ
    매우 어렵습니다 ;;;
  4. remake
    비트나미 설치 시 오류로 MAMP(https://www.mamp.info/en/)를 깔아서 실습하고 있는데, 보안2의 예제
    alert(merong)이 아예 데이터베이스로 전달되지 않네요. 실습해보고 싶었는데 뭔가 AMP내부적으로 스크립트 문을 받아들이지 않는 설정이 되어 있는 듯합니다. 호오...
  5. JIbt
    OWASP10 중에서 몇가지 내용이네요!
    정말 대단하십니다.. 보안 공부하면서 뭔가 와닿지 않았던 내용인데
    이렇게 직접 보여주시니깐 정말 머리에 쏙쏙 박히네요 ㅎㅎㅎ
  6. 박인호
    11-28
    수강완료.
    상당히 중요할 수 있는 내용이군요, 감사합니다.
  7. 서성진
    ㅠㅠ 많이 어렵고, 또 이번엔 졸음이 쏟아져서..
    절대 재미없거나 흥미가 없어서는 아닌데,,
    어려워서 그랬던 것 같습니다. 정신 차려가면서 끝까지 맨정신으로 보느라 힘들었네요. ㅎㅎ
    그래도 본 보람은 있었네요.
    감사합니다. 잘 봤습니다.
  8. 효천
    어렵네요
    하지만 중요한 부분 같습니다.
  9. 유상원
    2017-11-11 완료!
  10. I love computer
    아우 어렵다ㅠㅠㅠ
  11. JH Chae
    수강 완료했습니다 감사합니다!!

    한가지 여쭤볼 것이 있는데요,

    $conn = mysqli_connect("localhost", "root", 111111);
    위에서 해당 서버에 접속하면서 password를 입력하게 되는데 프로그래밍하는 입장에선 내부적으로 바로 드러나는데
    외부에서는 볼 수 없나요?
  12. Michael
    완료~!
    감사합니다.~!
  13. 송성태
    알고 보니까 섬뜩합니다.
    보안이 없으면 그냥 정보를 공개하는 것과 마찬가지군요.
    뭐하나 그냥 넘어갈 내용이 없군요.
    잘 보았습니다.
  14. hunter10
    완료
  15. 왓떠뻐꺼
    완료했습니다. 감사합니다.
  16. var_dump 해서 나온 값이 항상 6이 나오는데 뭐가 잘못된걸까요?ㅠ
  17. kulung
    process.php 코드내에 password 도
    $password = mysqli_real_escape_string($conn, $_POST['password']); 를 넣어줘서
    조건문을 $sql = "INSERT INTO user (name, password) VALUES('".$author."', ".$password")";
    하면안..되는건지요? @@ 어렵네용
  18. Gyoil Gu
    여러번 돌려봤어요! 보안은 어렵고 중요하네요.
  19. 다시시작
    완료
  20. jayxwoo
    잘봤습니다^^ 이런식으로 escaping을 한다는 감각을 조금은 알 것 같네요. 감사합니다~
  21. jayxwoo
    설명을 잘 못드린 것 같네요. (정확하진 않다고 말씀드리긴 했지만..)
    보안3 동영상을 보니 원화 표시는 역슬래시를 사용하는 것 같네요. 보안3 동영상 25분20초 부터 한번 보세요. ^^
    대화보기
    • jayxwoo
      맥os에서는..
      - 원화(₩) 표시 대신 키보드버튼 1 왼쪽에 위치한 ` 버튼을 사용하는 것으로 알고 있습니다.
      - 원화 표시를 해야 할 경우 키보드 인풋을 한글로 변경하신 후 위와 동일한 버튼 ` 을 누르시면 원화로 표시됩니다.

      (정확하진 않지만 한번 해보세요.)
      대화보기
      • forest
        완료
      • thank you so much ^^
      • 김태윤
        봤어요.. 근데 어렵네요. --;
      • Narrativi
        $_GET[] 으로 받으려고 하는 name과 password를 찾을 수 없다는 뜻입니다.
        아마 주소에 ?name=egoing&password=111111 를 덧붙이는걸 깜박하신 것 같네요!

        localhost/phpjs/14.php 로 이동하면 보시는 에러메시지가 뜨고
        localhost/phpjs/14.php?name=ㅁㄴㅇㄹ&password=ㅁㄴㅇㄹ 로 이동하시면, ㅁㄴㅇㄹ에 입력한 내용에 따라 '반갑습니다' 또는 '뉘신지'가 뜨게 됩니다.

        if문을 응용하시면 name 또는 password가 빠진 경우에도 에러메시지가 출력되는 대신 빈페이지를 보이게 한다거나 하실 수 있습니다!
        대화보기
        • 광길
          보안 실습 3번 코드를 작성하고 리로드를 하면

          Notice: Undefined index: name in C:\Bitnami\wampstack-5.6.31-0\apache2\htdocs\phpjs\14.php on line 4
          //(4번줄 내용 : $name = mysqli_real_escape_string($conn, $_GET['name']);)
          Notice: Undefined index: password in C:\Bitnami\wampstack-5.6.31-0\apache2\htdocs\phpjs\14.php on line 5
          //(5번줄 내용 : $password = mysqli_real_escape_string($conn, $_GET['password']);)
          SELECT * FROM user WHERE name='' AND password='' 뉘신지?

          자꾸만 이렇게 뜹니다ㅜㅜ 데이터베이스에 이름을 다르게 저장한것도 아닌데 왜그러는 걸까요??ㅠㅠㅠ 도와주세요ㅠㅠㅠ
        • 신시내티
          수업 듣고보니 보안 전문가는 암환자를 수술하는 외과의사 같다는 생각이 드네요 ㅎㅎ
          미국에서는 금융계 회사 보안 전문가가 IT 업계에서 가장 대우받는 직업중 하나 인것 같아요.
        • 신시내티
          이고잉님 수업에는 단순한 스킬뿐 아니라,철학도 담겨있어서 좋아요. 감사합니다.
        • jhpark
          Wow, safety is vary important.
          i think, i can see that.
        • chosu1202@naver.com
          원화 표시라는 것 보다는 역슬래쉬라는 것을 아셔야 할 것 같습니다.
          Enter 바로 위에 있는 버튼 누르시면 됩니다.
          대화보기
          • 가영
            완료!
          • Jayden贤宇
            맥북은 mysql monitor에서 원화표시를 어떻게해야하죠??

            control + command + space 단축기로 원화를 넣으면 오류가 뜹니다..ㅠㅠ
          • qhdgusdndn@naver.com
            맥북은 mysql monitor에서 원화표시를 어떻게해야하죠??

            control + command + space 단축기로 원화를 넣으면 오류가 뜹니다..ㅠㅠ
          • GoldPenguin
            완료했습니다.
          • milhouse
            도움이 될지 모르겠지만 일단 작성해볼게요.^^

            -> $sql 변수에 DB안에서 실행하고 싶은 명령어를 문자열 형태로 저장한 다음

            mysqli_query 함수를 통해 DB내에서 $sql에 저장된 문자열을 전달해서

            그 문자열을 명령어로 실행시키도록 하고 있는 거라고 알고 있습니다.
            대화보기
            • Baekkyu Han
              보안
              보안1~3
              낙법 실패하는법 성공을 자신있게 도전
              복구 불가능한것은 데이터
              적절힐 비극은 엔지니어의
              좋은 엔지니어는 비극속에서 피어나는 꽃
              좋은 습관은 자신을 지킨다.

              dbase 관련 보안
            • 박예지
              완료료료
            • 김경태
              잘 봤습니다~
            • Myeongjin Ko
              완료
            • 인재진
              수강완료합니다.
            • 완료 ^^
            • fatfat
              수업 잘 들었습니다 ㅎㅎ 수업을 듣다가 궁금한게 생겼는데요!

              DB에서 가져온 내용을 화면에 표시하기 전에 script 태그를 무력화 시키는 방법은 이제 앍았습니다.

              그런데 제 생각에 DB의 내용이 공격을 당했을 수도 있으니 DB에서 가져온 내용을 좀 더 꼼꼼하게 따져봐야 하는것 아닌지 하는 괜한 걱정이 드네요..

              실제 홈페이지를 만들 때 DB에서 가져오는 내용은 script만 무력화 시켜줘도 충분한가요??
            • 김코코
              $sql = "SELECT * FROM user WHERE name='".$_GET['name']."'AND password='".$_GET['password']."'";

              이 코드에서 sql에 들어가는건 문자열인가요 아니면 db를 이용하는 어떤 명령문인가요?
              " " 이것을 이용해 쭉 나열한 문자열이 sql 변수에 들어간 거같은데...
              음 저 코드가 사용자가 입력한 name과 password를 받아서 뭘 하는지 잘 모르겠어요
            • 지구촌
              보안이 어려워요.
            • 푸른바람9101
              열심히..
            • 김범진
              휴 보안에관해 한번하고싶었었는데 좋네요 완료
            • 한종운
              [보안]
              보안1
              정보 business 핵심 요소. code(x) data(o)
              서버는 data의 집. 서버에 접속할 때는 '경건'하라.
              서버 작업에서의 실수는 돌이킬 수 없는 경우가 있다.
              좋은 엔지니어는 '비극속에 피어나는 꽃'이다.
              적절한(?) 보안 비극은 보안 담당자에게는 '약'이다.
              보안 전문가는 만능이 아니다.
              보안은 포괄적인 보호수단.
              보안에 대한 좋은 습관이 필요.

              보안2
              HTML Entity

              text를 있는 그대로 표시하는
              php 함수
              echo htmlspecialchars(" ")
              사용자가 직접 입력한 정보는 공격 대상이 될수 있으므로
              htmlspecialchars()로 모두 감싸서 보호하라.

              php.net에서
              strip_tags 검색. 사용방법 확인 가는.
              strip_tags : 태그를 날리고, 허용태그를 직접 지정 할 수 있다.

              보안3
              dbase 보안
            • 좋은 강의 감사합니다!!
            • kong il
              보안3 실습할때,

              Notice: Trying to get property of non-object in C:\Bitnami\wampstack-5.6.31-0\apache2\htdocs\phpjs\14.php on line 15

              브라우저 창에 이거 같이 뜨면서 결과값은 똑같이 나오는데 맞는건가요?
            버전 관리
            egoing
            현재 버전
            선택 버전
            graphittie 자세히 보기