웹 애플리케이션 만들기

보안

보안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. 참 고맙습니다.
  2. 손영민
    escaping, 웹사이트에서 엄청 중요하지만, 반면에 문제가 생기기 전까지는 아무도 신경쓰지 않는 것.
  3. Comtroll
    view-source:http://localhost:8080/write.php

    write.php 페이지에서 소스 확인해보시면 패스워드 노출 안됩니다.
    잘 생각해보면 알 수 있죠
    대화보기
    • Comtroll
      port 문제가 얽혀서 헤매시는 분들 많을 것 같네요.

      강의에서는 80 port로 서버를 진행하고 있어서 접속 주소에 localhost:8080로 포트를 표시하는 부분이 없습니다.
      http에서는 port가 명시되지 않으면 규약인 80이 포트로 사용됩니다.

      Linux에서는 현재 well known port (0~1023) 로 서버를 여는데는 sudo 권한이 필요한 것 같습니다.
      그래서 bitnami configure에서 apache server의 port를 80으로 설정해도 안되죠.

      강의자분처럼 root 디렉토리 bitnami를 설치하거나, 모든 주소에 :8080을 붙여서 사용하시면 될 것 같네요.
      데이터베이스 주소는 데이터베이스 port로 사용하셔야 하고요.
      mysqli에서 default로 쓰는 port는 3306 이라, 3306으로 사용 중이면 주소에 :3306 안해도 됩니다.
    • 조동재
      htmlspecialchars($row['title']) 에서 $row['title']은 문자열 값을 가지고 있는 거 아닌가요?
      그러면 htmlspecialchars('$row['title']') 이 되야 하는 거 아닌가요...? 부족한 질문이지만.. 감사합니다
    • 김민환
      어려운 내용이라서 개념만 대충 배워갑니다. 복습이 중요하군요. 복습... ^^;
      항상 감사합니다.
    • 슝태
      20180119
    • PassionOfStudy
      18-01-09 11일차 - 2번째 강의

      수강완료!


      ----------------------------------------------------------------------------------
      본래 보안에 관심이 있는 1인으로서 신기하고 재미있네요~

      Secure Coding이라는게 이런 것을 생각함으로써 시작하는 것일까요???
    • hanulsso
      반복학습이 필요한 수업이네요
      여러번 복습하겠습니다.
      저런게 보안이었군요 재밌습니다 어렵지만
    • 이근환
      2017-12-12 수강 15일차

      수강완료하였습니다.

      htmlspecialchars와 strip tags, mysqli_real_escape_string을 배우고

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

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

      $conn = mysqli_connect("localhost", "root", 111111);
      위에서 해당 서버에 접속하면서 password를 입력하게 되는데 프로그래밍하는 입장에선 내부적으로 바로 드러나는데
      외부에서는 볼 수 없나요?
    • Michael
      완료~!
      감사합니다.~!
    • 송성태
      알고 보니까 섬뜩합니다.
      보안이 없으면 그냥 정보를 공개하는 것과 마찬가지군요.
      뭐하나 그냥 넘어갈 내용이 없군요.
      잘 보았습니다.
    • hunter10
      완료
    • 왓떠뻐꺼
      완료했습니다. 감사합니다.
    • var_dump 해서 나온 값이 항상 6이 나오는데 뭐가 잘못된걸까요?ㅠ
    • kulung
      process.php 코드내에 password 도
      $password = mysqli_real_escape_string($conn, $_POST['password']); 를 넣어줘서
      조건문을 $sql = "INSERT INTO user (name, password) VALUES('".$author."', ".$password")";
      하면안..되는건지요? @@ 어렵네용
    • Gyoil Gu
      여러번 돌려봤어요! 보안은 어렵고 중요하네요.
    • 다시시작
      완료
    • jayxwoo
      잘봤습니다^^ 이런식으로 escaping을 한다는 감각을 조금은 알 것 같네요. 감사합니다~
    • 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
                완료
              • 인재진
                수강완료합니다.
              • 완료 ^^
              버전 관리
              egoing
              현재 버전
              선택 버전
              graphittie 자세히 보기