웹 애플리케이션 만들기

보안

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

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

    url에 추가한 ' or '1'='1' 문을 ' or '1'로 해도 됩니다.
    '1'='1' 은 항상 true 인데, '1' 자체로도 항상 true 이니까요.
  9. JustStudy
    고맙습니다 2.
  10. 이주환
    2016. 4. 14.
    정독했습니다.
    보안의 중요성은 숙지할수밖에 없는 사항이죠.
  11. JustStudy
    고맙습니다
  12. 반가운 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 할때터 버그가 창궐하더니만, 저게 문제였네요. 더러운 책상에서 고민거리 가득한 상태로 했더니 야예 다시 짜야 하는 버그가 생겼습니다. 조금만 더 일찍 말씀해 주시지ㅠㅠㅠㅠㅠ(물론 이건 농담입니다.)
      • 얼그레이티
        언제나 훌륭한 강의 감사합니다~^*^!

        그러나 3번째 강의를 보며 실습하는 도중에 풀리지 않는 것이 있어 질문드립니다.

        14.php의 $result의 값이 객체화 되지 않았는지
        if문 부분이 실행되지 않고 else만 실행되며 아래와 같은 경고가 뜹니다.

        Notice: Trying to get property of non-object in C:\wamp\www\phpjs\14.php on line 16(if문 구절)

        var_dump('$result')의 결과도 string '$result' (length=7) 이렇게 뜨네요.


        무엇이 문제 인걸까요?

        ======================================================================

        아이고~ $sql 입력값에 오류가 있었네요. AND와 password 사이에 ' 기호가 있었습니다. 하하

        혹시나 똑같은 문제로 고생하실 분이 계실까봐 질문 안지우고 남겨놓겠습니다^^
        오타를 조심합시다ㅠㅠ 열공하세요~!
      • 야쿠
        감사합니다~
      • 황민철
        좋은 강의 고맙습니다
      • 쪽빛하늘
        감사합니다. 보안에 대한 내용만 이해하고 넘어가요.
      • 발없는방랑자
        고맙습니다.^^
      • 유종수
        보안 3. 영상 정말 대단했습니다. 이렇게 막는것도 있군요. 대박이에요^^
      • 애국컴공과
        어차피 글번호에 맞는 내용만 띄워주면 되니까

        $sql = "SELECT * from topic where id=".$_GET['id'];

        음.. index.php 파일에 하단 php 부분 보시면 sql문 변수 선언한 내용을 위처럼 바꾸시면

        그리고 유저테이블을 생성한다고 해결이 되는게아니라

        $sql = "SELECT topic.id,title,name,description FROM topic LEFT JOIN user ON topic.author = user.id WHERE topic.id=".$_GET['id'];

        아마 복붙을 해보셨다면 이렇게 sql문이 되있을텐데요 이거는 user테이블과 topic 테이블을 조인해서 값을 얻어오는 구조기 때문에 지금 안맞는 데이터를 넣으시면 null값이 반환되거나 할겁니다.

        위에 sql문으로 간단하게 바꿔보세요.
        대화보기
        • MABIN
          서현님/ 관계형 데이터베이스 수업에서 USER라는 테이블 만들고 부속적으로 뭐 추가하는데 그거 참고 하고 오시면 될거같아요!
        • 서현
          언제나 좋은 강의 감사합니다.
          서버쪽 언어가 너무 알고 싶어서
          오늘 아침부터 강의 정주행하고 있습니다...
          프론트쪽부터 서버까지...한번에 주욱 듣게 되니 뻥 뚫리는거 같아요..
          여기까지는 잘 따라왔는데...

          보안3 강좌에서...
          갑자기 user 테이블이 나오는데... 우리가 user 을 만들었던가요?
          일단, 갑자기 튀어나온 user 테이블에 한번 놀라고...

          계속해서.var_dump($result);의 결과값이 bool(false) 로 나오는 것 때문에 진도가 막혔습니다..

          이고잉님 코드에서 해당부분을 복사해서 계속 붙여보는데도...결과가 변하지 않아요.
          뭐 때문일까요..



          -------------

          네...수업의 분량문제로...이 부분은 대략만 다루신다는 설명이...바로 뒤에 나오네요...
          덕분에...user 테이블 만들고...데이터 넣고...그랬네염...ㅋㅋ

          그렇지만...user 테이블 생성했음에도...저 에러는 계속됩니다. 뭘 잘못했을까요...
        • 스캣
          엄청 빠져들어서 수업을 들었습니다. 보안 정말 조심해야되는 부분이네요.
          유용한 강의 감사합니다.^^
        • 비티민C플러스
          감사합니다^~^
        • 서드몽키
          전체 구문을 올리는게 도움되지 않을까요?
          대화보기
          • garimtou@gmail.com
            보안을 배우긴 했지만,
            반대로 크랙의 기본을 배우기도 했네요
            좋은 강의 고맙습니다
          • 코딩!
            보안이라는게 따로 프로그램을 설치하는 방법만 있는줄 알았는데,
            코딩할 때 우회하는 방법으로 해킹을 방지할 수 있나 보네요!
            이러한 방식은 절때 못 뚫는 최고의 방법인지 궁금해지네요 !
          • 허니버터
            보안의 중요성을 다시 한번 알게 되어서 좋았습니다.
            고맙습니다.
          • Dreadsnout
            '보안3' 강좌에서, 브라우저 URL 입력창에, password=(아무거나)' or '1'='1 을 입력하는 과정에서, sql문을 echo로 출력해 보면 ' 만 타이핑했는데 ' 옆에 \가 붙어서 나와 SQL Injection 테스트가 되지 않습니다. mysqli_real_escape_string도 적용하지 않은 상태인데 무엇이 문제인 걸까요?

            select * from user where name='egoing' and password='abcd\' or \'1\'=\'1' <-이런식으로 나옵니다ㅠㅠ IE, Firefox, Chrome 세 브라우저에서 모두 시도해봤는데 결과가 같네요
          • 이준행
            좋은강의 감사합니다!!
          • anonziny
            SQL Injection 기본 설명까지 해주시다니 감사합니다.
            이고잉님 감사합니다.
          • 감사합니다.
          • 감사합니다.
          • goback19
            비유가 정말 주옥 같네요..감탄합니다 툴도 잘 쓰시고 강의시간을 줄이기 위해 많이 연습하신건지 준비가 잘 된 강의라는게 팍팍 느껴집니다 학교 교수님들도 이렇게 강의해주면 얼마나 좋을까요..ㅠ
          • 어부바
            감사합니다.
          버전 관리
          egoing
          현재 버전
          선택 버전
          graphittie 자세히 보기