서버는 데이터의 집 - 서버에 접속할 때는 신중하게!


보안에 대한 좋은 습관? -> 좋은 습관은 자신도 모르게 자신을 비극 속에서 지켜준다!


보안1 - 사용자 입력값을 받아 데이터 저장할 때 사용자가 script 태그를 넣어 광고 등을 넣을 위험으로부터 차단


< 과 >는 그냥 쓰면 태그의 시작과 끝을 알리지만


php 내장 api 중 htmlspecialchars() 를 이용하면 ()안에 들어가는 각종 기호를 문자로서의 기호로만 인식한다.


ex) <script>aleart(1);</script>'); 을 그냥 치면 화면에 경고창이 출력되지만


 htmlspecialchars('<script>aleart(1);</script>');') 이렇게 하면 화면에 <script>aleart(1);</script>'); 문자 그대로 출력된다.



사용자 입력창에 적용하여 태그 쓰는 걸 방지하자!


article의 제목과 저자에 태그 적용


echo '<h2>'.htmlspecialchars($row['title']).'</h2>';

echo '<p>'.htmlspecialchars($row['name']).'</p>';


※ 태그가 포함된 컨텐츠에 이 api를 적용하면 모든 태그가 적용이 안되기 때문에 다른 방법을 쓴다.


strip_tags -> 태그를 벗겨냄 (태그를 적용 안되게 하는 태그)


strip_tags($row['description'],'<a><h1><h2>');


-> a,h1,h2 태그는 적용하고 나머지 태그는 적용하지 않음(문자 그대로 출력)


보안2 - 아이디와 비밀번호에 문법에 사용되는 기호가 문자로만 인식되도록 하는 방법


조치를 취하지 않았을 경우 발생하는 문제


SELECT * FROM user WHERE name='egoing' AND password='111111'; -> 아이디 egoing 과 비번 111111을 모두 만족하는 정보만 출력 


SELECT * FROM user WHERE name='egoing' AND password='111111' OR 1=1;  OR 뒤의 1=1은 언제나 ture이기 때문에 모든 정보가 출력됨




$conn = mysqli_connect('localhost','root','minu1312');

mysqli_select_db($conn, 'opentutorials');

$sql = "SELECT * FROM user WHERE name='".$_GET['name']."' AND password='".$_GET['password']."'";

$result=mysqli_query($conn,$sql);


-> 주소창 http://localhost/phpjs/14.php?name=&password=    name과 password의 입력값이 모두 만족하는 정보를 조회할 것을 서버에 요청함



  <?php

  if($result->num_rows == "0") {

    echo "뉘신지?";

  } else {

    echo "주인님 환영합니다";

  }

   ?>


특정 name과 password를 모두 만족하는 정보는 단 하나이므로, 올바르게 썼다면 $result->num_rows (리턴된 행의 갯수)는 1개이다. 


위의 조건문은 네임과 페스워드 중 어느 하나라도 맞지 않으면 "뉘신지" 라는 메세지가 화면에 출력된다.



BUT  아이디: eoging 비번: 2222 인데


만약 주소창에 http://localhost/phpjs/14.php?name=egoing&password=111111' or '1'='1 로 입력된다면? 


SELECT * FROM user WHERE name='egoing' AND password='111111' OR '1'='1';


-> or '1'='1'을 포함한 완벽한 sql문이 만들어짐. 즉 모든 행의 정보에 관해서 true가 되어 패스워드가 틀렸는데도 불구하고 "주인님 환영합니다"로 뜸 (보안이 뚫림)



해결방법


'를 문자'로 표시하는 방법 \'


아이디와 패스워드 안에 문법에 사용되는 문자(ex '')를 문자로만 표시되게 하는 내장 api 사용 


-> mysqli_real_escape_string($conn,$_GET['name'])


http://localhost/phpjs/14.php?name=eg'oing 이렇게 넣으면 eg\'ing로 표시됨


$conn = mysqli_connect('localhost','root','minu1312');

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;  화면 출력되게 하고


http://localhost/phpjs/14.php?name=egoing&password=asdfdss' or '1'='1  치고 접속하면


화면에 SELECT * FROM user WHERE name='egoing' AND password='asdfdss\' or \'1\'=\'1' 라고 뜸으로써


패스워드 안의 '가 \'로 표시 됨으로써 모두 문자처리 됐음을 확인 할 수 있다. 즉 여기서 패스워드는 asdfdss' or '1'='1 이 되고

패스워드가 맞지 않으므로 뉘신지? 가 뜬다.


 







'프로그래밍 > 코딩야학' 카테고리의 다른 글

라이브러리 이론, 실습1  (0) 2017.06.21
관계형 디비 이론, 실습  (0) 2017.06.20
데이터베이스 실습  (0) 2017.06.19
데이터 베이스  (0) 2017.06.19
PHP 실습  (0) 2017.06.16
복사했습니다!