웹 애플리케이션 만들기

보안

보안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. 우탄
    재미따리 재미따~
  3. 14번째
    4.3.
  4. 보안까지 챙겨주셔서 감사합니다~
    역시 아무리 강조해도 지나치지 않네요.. ^^
  5. 세번째 영상의 2:13초에 패스워드를 asdfdsa' or 로 치면

    오류가 나는 sql문이 된다고 하셨잖아요.

    그러면 $result값이 NULL이 되고 if문 안의 값도 NULL이 되어서

    else에 해당하는 안녕하세요 주인님이 나오게 되는건가요?
  6. publicum
    혹시 다른 브라우저를 쓰시는 분들 참고하시라고 남겨드립니다.

    이고잉님께서 3번째 영상 중에 공격자가 URL 조작으로 SQL에 항상 참인 호출을 넣는 사례를 보여주셨는데, 기존 URL 뒤에 한칸 띄어서 OR를 붙이는 공격예제를 일부 브라우져에서는 제대로 인식하지 않고 잘못된 주소로 처리해서 구글 검색으로 넘어가버립니다. 찾아보니 본래 URL에서의 스페이스는 '+'기호나 '%20'로 표시되는 군요. 즉, 한칸띄기 대신 +를 입력하시면 똑같은 효과로 예제를 따라가실 수 있어요.
  7. Jaeeui Kwon
    20170317
  8. 170307
    감사합니다.
  9. <script>
    </script>
  10. 강경호
    감사합니다
    170228
  11. Gunho Lee
    안녕하세요 질문있습니다.
    2번 강의에서 본문에 자바스크립트 내용을 입력하고 제출하면 데이터베이스에 추가가 안됩니다.
    유저 테이블에 새로운 id가 등록되긴 하는데 topic테이블에는 추가가 안되네요.
    본문에 그냥 일반 문서를 치면 잘 업데이트가 되는데 자바스크립트 내용을 쓰면 안됩니다.
    이건 왜 그런건가요?
  12. egoing
    여기까지 오셨으면 여기서 멈추셔도 괜찮습니다. 이미 덜 중요하고 훨씬 어려운 개념들의 구간에 들어서셨거든요~
    대화보기
    • 가뭉멍
      여기까지 잘 달려왔는데... 비록... 3개월이나 걸렸지만... ㅠㅠ 생초보에게는 데이터베이스 이후로 갑자기 너무 진행이 빠르고 어려워지는 느낌이예요.. 보안 강의만 대여섯번씩 다시보는 중..그래도 끝까지 포기 안하렵니다..!!
    • 아니먼데
      잘됬는데 위에코드 복사해서 넣으니까 자꾸 이상한거나옴
      경고 : mysqli_fetch_assoc ()는 매개 변수 1 부울에 주어진, mysqli_result 될 것으로 예상 D : Bitnami \ wampstack-5.6.29-0 \ 아파치 \ htdocs에 \ index.php에 \ 라인 (36)
      이거뜨면서 자꾸 않나옴 전엔잘됬는데 2번쨰 index.php복붙했더니 이럼
      36번쨰라인
      $row = mysqli_fetch_assoc($result);이거임
    • 문돌이
      object(mysqli_result)#2 (5) { ["current_field"]=> int(0) ["field_count"]=> int(3) ["lengths"]=> NULL ["num_rows"]=> int(1) ["type"]=> int(0) } 주인님 환영합니다

      http://localhost......111

      주신 코드를 넣어보니 저한테는 나타나는 것을 보니, 제 생각에는 코드의 문제가 아니라 설정의 문제 같습니다.
      어렵네요..ㅠ
      대화보기
      • 호미타
        <?php
        $conn = mysqli_connect("localhost", "root", "문자로된비번");
        mysqli_select_db($conn, "opentutorials");
        $sql = "SELECT * FROM user WHERE name='".$_GET['name']."'AND password='".$_GET['password']."'";
        $result = mysqli_query($conn, $sql);
        var_dump($result);
        ?>
        입력한 코드입니다ㅜ echo로 sql문 작동 확인했을 때는 잘 작동했는데, 결과 값이 안나오네요ㅠㅠ

        http://localhost......111
        주소창에 넣은 입력 값이구요..
        object(mysqli_result)#2 (0) { } 뉘신지?
        이게 출력된 내용입니다;ㅁ;
        뭐가 문제인지 모르겠어서 헤매이고있습니다ㅠㅠ
        대화보기
        • 문돌이
          혹시 그 이전 코드랑 크롬 주소창에 적으신 데이터를 보여주실 수 있나요..?
          데이터가 입력되는 활동이 일어나지 않아서..그런 것 같기도 하구요..
          대화보기
          • 호미타
            질문자님은 아니지만 질문자님과 똑같은 문제로 고민중인데요, echo 출력 구문을 지워도
            var_dump의 값이
            object(mysqli_result)#2 (0) { } 뉘신지?
            이렇게만 뜹니다. 아무리 찾아봐도 모르겠네요ㅠㅠ
            대화보기
            • 노노재노재노창
              재밌는걸~
            • 문돌이
              echo sql; 이것 지워보시는 건 어떠신가요..?
              대화보기
              • 나홀로문도리
                좋은 강의 감사합니다~!
                잘 들었습니다!
              • 이성진
                수강 완료!
                좋은 강의 항상 감사 드립니다~
              • write.php에서 비밀번호 입력하는 부분이 원래 있어야 하나요?
              • 보안3 강의에서요.
                $sql = "SELECT * FROM user WHERE name ='".$_GET['name']."'AND password='".$_GET['password']."'";
                echo $sql;
                $result = mysqli_query($conn,$sql);
                var_dump($result);

                이렇게 php 코딩을 했는데 출력되는 $sql은 제대로 나오는데
                var_dump($result); 이 부분이 동영상과는 다르게
                object(mysqli_result)#2 (0) { } 이렇게만 떠요.. 왜그럴까요ㅜ
              • 열공인
                안녕하세요. 이제까지 잘 써왔는데요. 어제 컴퓨터 시작할 때 패스워드를 바꿨네요. 그것 때문인지 오늘 cmd에서 mysql들어 가려고 하니, the system cannot find the path 라고 나오네요. 그런데 실습 프로그램은 또 작동을 하는 것 같아요. cmd에서만 들어갈 수가 없는 상황?? 제가 잘 몰라서 상황이 어떤지도 솔직히 파악을 못하겠는데요. bitnami를 다시 설치해야 할까요? 감사합니다.
              • 김종엽
                2016.08.10 완료 !
              • 구녹수수
                근데 phpjs에서 8.php를 한게 아니고 8-1과 8-2로 나눠서 하지 않았나요??
                똑같이 8.php를 만들어서 해보니까
                undefined index : password라고 뜨는데
                이고잉님 처럼
                localhost/phpjs/8.php를 하면 저런 오류가 뜹니다.
                아무것도 넘기지 않았는데 뉘신지 가 안뜨고 오류가 뜨는데
                어떻게 해야하나요???
              • 차누
                수강완료
              • Wookiiis
                잘 보았습니다. :)
              • 김유성
                너무 재밌네요. 감사합니다.

                다른 분들을 위해 조금 남겨 해봅니다.

                url에 추가한 ' or '1'='1' 문을 ' or '1'로 해도 됩니다.
                '1'='1' 은 항상 true 인데, '1' 자체로도 항상 true 이니까요.
              • JustStudy
                고맙습니다 2.
              • 이주환
                2016. 4. 14.
                정독했습니다.
                보안의 중요성은 숙지할수밖에 없는 사항이죠.
              • JustStudy
                고맙습니다
              • 반가운 C 개발자네요.
                C언어는 절차지향적 성격이 강하지만,
                C언어를 더 깊이 파시다 보면 객체지향도 알게 될겁니다.
                (물론, 다중패러다임 언어인 C++이나 순수객체지향 언어인 Java를 배우신다면
                제대로 된 객체지향을 배우시겠지만요.)

                객체지향적 디자인은 프로그래밍에 있어 매우 중요하고 유용하기 때문에,
                C언어에서도 언어적으로 지원되진 않지만 라이브러리나 프레임워크를 통해
                "일부" 구현하는 모습을 종종 볼 수 있습니다(매크로의 힘은 무한합니다).

                예로, 윈도우즈 커널드라이버 프레임워크는 성능문제 때문에 C언어를 채택했지만
                (유저드라이버 프레임웤은 C++ API를 지원합니다.)
                객체지향적 API를 제공하지요.

                C언어는 그 역사만큼 굉장한 깊이가 있기 때문에
                꾸준히 공부하신다면 무한한 재미를 느끼실 수 있을겁니다.
                대화보기
                • 3번강의 수강하시는 분들이 약간 헷갈릴 수 있을 것 같아 덧붙이자면,
                  name='egoing' AND password='111111' OR '1'='1'

                  이부분 설명하실 때 앞에서는 비밀번호가 '111111'이 참이거나 '1'이 '1'이 참이면 참이라고 설명하시고
                  뒤에서는 OR 앞 전체와 뒤 전체 중에 하나가 참이면 참이라고 하셨습니다.

                  예제에서는 뒤에 설명하신게 맞고,
                  그 이유는 연산자들의 우선순위 때문입니다.
                  괄호가 없을 때, 기본적으로 각 연산자(==, >=, OR, AND 이런 것들)들 끼리 약속된 우선순위가 있는데요

                  수학에서도 곱하기가 더하기보다 먼저인것처럼
                  비교연산(부등호/등호) -> AND -> OR 순으로 우선순위가 높습니다.
                  그렇기 때문에 이름과 비밀번호가 AND로 먼저 묶이고,
                  이후에 뒤 식과 OR가 되게 됩니다.
                • Kyu Tae Kim
                  eye-opening lecture!
                  웹에서 보안이 중요하다는게 이런 방식으로 되는걸 말하는구요. 정말 몰랐었는데, 재미있네요. 감사합니다.
                • 채광은
                  웹보안 공부하려는 학생입니다 .

                  보안 공부할려면 일단 웹 사이트부터 만들고 하는게 좋나요??
                  아님 오폰소스를 가지고 웹보안 공부하는게 좋나요????
                • 김트라슈
                  잘 봤습니다. 근데 궁금한게 PPT에 나오는 이미지는 직접 그리시는건가요? 유도복 엄청 잘 그리시네요.ㅋ
                • openarms
                  php.ini 파일안에서 opcache.enable 을 검색해서 1로 되어있는 값을 0으로 바꿔주시면 refresh를 했을때 바로바로 적용이 됩니다.
                  대화보기
                  • 호세마리아구토
                    역시 코딩은 많은것들의 예외처리를 항상 염두해두어야 하죠...
                    전 C개발자라서 강의에서 나오는 순차적인 코딩스타일이 익숙한데
                    마지막 강의에서 얘기해주셨던 객체지향 스타일 코딩은 어떤식으로 한다는것이 궁금해지네요.

                    꾸준히 모든 강의를 섭렵해야겠군요
                  • ironboy
                    요번 강의는 흥미롭기도 하고..어렵네요. ㅎㅎㅎ
                    매력있습니다 이번 강의!
                  • MW.LEE
                    안녕하세요! 이고잉님 수업 잘 따라오고 있습니다.
                    그동안 이론수업에서 많이 들어왔으면서 관례로 생각하고 이해하지 않고 넘어갔던 부분들이 이해를 할수 있게 해주셔서 갈증이 해소되는 느낌을 받고 있습니다.

                    그런데 한가지 궁금한 점이 생겨서 질문드립니다.
                    오류는 아닌데 PHP파일을 수정하고 나서 크롬에서 새로고침을 해서 확인하려고 하면
                    동영상속에서 보면 바로바로 반영이 되는것을 볼수 있는데 제 실습 환경에서는 거의 5초에서 10초가 지나야지만 반영이 되는것을 확인할수 있는데요 이것도 뭔가 톰캣의 환경변수거나 크롬에서의 환경변수값때문인 것인지 다른이유인것인지가 매우 궁금합니다.
                    어떤 경우에는 바로 적용되는것 같기도 하고 어떤 경우에는 새로고침을 수십번해야 반영되는것 같기도 하고 그러네요 이유가 무엇일까요?
                  • 황제웅
                    이고잉님이 중요한 부분에 들어가기 전 설명 해 주시는 방법을 듣고 있으면 감탄이 절로 나요
                    이해하기 쉽게 설명 해 주시는 건 기본이고 그 의미를 어떻게 받아들여야 하눈지에 대해서도 가이드를 잡아 주시는데,
                    어쩜 이렇게 설명을 잘 하시는지 부럽습니다.
                    경험하지 못 한 감정에 대한 공감이 추상적이다. 라는 것에 공감하면서 정말 중요한 목적이 어떤 것인지 생각 해 보면서 동영상 볼게요
                    잘 보고 있고 이렇게 동영상 올려 주셔서 감사합니다.
                  • 이현수
                    잘봤습니다. 여기까지 왔네요.
                  • 오빠는다르다
                    머리가나빠서...ㅠㅠ

                    감사합니다!!!
                  • Cherry Jeon
                    와우...3번째 동영상 진짜 어렵네요...
                  • hackbyr0k
                    좋은 강좌 감사히 잘 보고 있습니다. 쵝오!!!
                  • sanoske
                    와우 크래커가 된 기분!
                  • SK Kim
                    도장 쾅!
                    기초 HTML 보안 -> htmlspecialchars(), strip_tags()
                    기초 DB 보안 ->mysqli_real_escape_string()
                  • 이제야 알았습니다.
                    서버에 접속할때는 경건한 마음으로 해야 합니다. 서버에 접속할때는 될수있으면 샤워를 하고, 옷도 갈아입고, 책상도 치우고, 고민거리가 있으면 나중에 접속하고 하세요
                    --이고잉--
                    DB 할때터 버그가 창궐하더니만, 저게 문제였네요. 더러운 책상에서 고민거리 가득한 상태로 했더니 야예 다시 짜야 하는 버그가 생겼습니다. 조금만 더 일찍 말씀해 주시지ㅠㅠㅠㅠㅠ(물론 이건 농담입니다.)
                  버전 관리
                  egoing
                  현재 버전
                  선택 버전
                  graphittie 자세히 보기