보안 XSS

 

Cross Site Scripting 을 줄여서 XSS라고 부른다

 

사이트에서 update를 하고

 

본문에

 

<script>alert('hi')</script> 이런식으로 작성하게 되면 경고창을 띄울수도 있고

 

<script>Location.href='https:www.naver.com';</script> 이렇게 입력하면 다른 사이트로도 보낼 수 있다

 

이 문제점을 막으려면 htmlspecialchars를 이용하면 된다

 

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>XSS</title>
  </head>
  <body>
    <h1>Cross site scripting</h1>
    <?php
    echo htmlspecialchars('<script>alert("babo");</script>');
    ?>
  </body>
</html>

 

위와 같이 만들면 스크립트가 실행되지 않고 그냥 문자형태로 출력됨을 알 수 있다

 

이것을 페이지 소스보기로 보게되면

 

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>XSS</title>
  </head>
  <body>
    <h1>Cross site scripting</h1>
    &lt;script&gt;alert(&quot;babo&quot;);&lt;/script&gt;  </body>
</html>

이렇게 < > 같은 괄호들이 &lt &gt 이렇게 표현되었다

 

내부의 파일들도 보자

 

lib 디렉토리 내에 print.php 파일을 수정해야한다

 

<?php
function print_title(){
  if(isset($_GET['id'])){
    echo htmlspecialchars($_GET['id']);
  } else {
    echo "Welcome";
  }
}
function print_description(){
  if(isset($_GET['id'])){
    echo htmlspecialchars(file_get_contents("data/".$_GET['id']));
  } else {
    echo "Hello, PHP";
  }
}
function print_list(){
  $list = scandir('./data');
  $i = 0;
  while($i < count($list)){
    $title = htmlspecialchars($list[$i]);
    if($list[$i] != '.') {
      if($list[$i] != '..') {
        echo "<li><a href=\"index.php?id=$title\">$title</a></li>\n";
      }
    }
    $i = $i + 1;
  }
}
?>

title이라는 변수를 만들고 $list[$i] 이것을 htmlspecialchars로 묶어준다

 

근데 막상 이렇게 해버리면 이미지 태그라든지 줄바꿈 이라든지 필수적으로 해야할 것들을 못할 수 있으므로

 

이 땐 스트립 태그를 이용하면 된다

 

보안 파일 경로 보호

 

password.txt 파일을 만들고 아무거나 적어보자

 

http://127.0.0.1/index.php?id=../password.txt 를 검색하면

 

password.txt의 정보가 그대로 노출되게 된다

 

이것은 아주 심각한 일이다

 

php에는 basename 이라는 함수가 있다

 

function print_description(){
  if(isset($_GET['id'])){
    echo $_GET['id'];
    echo "<br>";
    echo basename("data/".$_GET['id']);
    echo "<br>";
    echo htmlspecialchars(file_get_contents("data/".$_GET['id']));
  } else {
    echo "Hello, PHP";
  }
}

이렇게 하면 ../password.txt 로 주소창에 검색 시

 

../password.txt

password.txt

적었던 내용

 

세가지의 경우를 알 수 있다

 

function print_description(){
  if(isset($_GET['id'])){
    $basename = basename($_GET['id']);
    echo htmlspecialchars(file_get_contents("data/".$basename));
  } else {
    echo "Hello, PHP";
  }
}

이러면 더이상 주소창을 이용해서 탐색할 수가 없다

 

UI API

 

UI 는 User Interface로 사용자가 보게 될 화면

 

API는 태그들 <a href="http://php.net"></a> 이러한 것들을 api라고 한다

'휴지통 > PHP' 카테고리의 다른 글

공부(9)  (0) 2021.09.07
공부(8)  (0) 2021.09.07
공부(7)  (0) 2021.09.07
공부(6)  (0) 2021.09.06
공부(5)  (0) 2021.09.06

글삭제

 

delete 버튼을 만들고 그 버튼을 누르면 바로 삭제되게끔 할 것이다

 

그렇기에 delete라는 링크는 필요없고 delete_process만 있으면 된다

 

파일을 지우는건 unlink()

 

삭제 또한 링크가 아닌 POST방식으로 해줘야한다

 

<?php
function print_title(){
  if(isset($_GET['id'])){
    echo $_GET['id'];
  } else{
    echo "Welcome";
  }
}
function print_description(){
  if(isset($_GET['id'])){
    echo file_get_contents("data/".$_GET['id']);
  } else {
    echo "Hello, PHP";
  }
}
function print_list(){
  $list = scandir('./data');
  $i = 0;
  while($i < count($list)){
    if($list[$i] != '.'){
      if($list[$i] != '..') {
        echo "<li><a href=\"index.php?id=$list[$i]\">$list[$i]</a></li>\n";
      }
    }
    $i = $i + 1;
  }
}
?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
      <?php
      print_title();
      ?>
    </title>
  </head>
  <body>
    <h1><a href="index.php">WEB</a></h1>
    <ol>
      <?php
      print_list();
      ?>
    </ol>
    <a href="create.php">create</a>
    <?php if(isset($_GET['id']))  { ?>
    <a href="update.php?id=<?=$_GET['id']?>">update</a>
    <form action="delete_process.php" method="post">
      <input type="hidden" name="id" value="<?=$_GET['id']?>">
      <input type="submit" value="delete">
    </form>
    <?php } ?>
    <h2>
      <?php
      print_title();
      ?>
    </h2>
    <?php
    print_description();
     ?>
  </body>
</html>

 

이제 delete_process.php를 보자

 

<?php
unlink('data/'.$_POST['id']);
header('Location: /index.php');
 ?>

unlink 즉 그 id에 해당하는 데이터 디렉토리 안의 파일을 삭제하고

 

인덱스 홈페이지로 이동해라 라는 뜻이다

 

파일로 모듈화 - require

 

리팩토링 작업을 해줄 것이다

 

좋은 코드를 만드는 아주 쉬운 실천 방법은 중복을 제거하는 것

 

재사용할만한 코드나 로직을 잘 정리정돈 해놓으면 도서관이라고 한다

 

제일 상단에 항상 중복되는 코드가 있다

 

<?php
function print_title(){
  if(isset($_GET['id'])){
    echo $_GET['id'];
  } else{
    echo "Welcome";
  }
}
function print_description(){
  if(isset($_GET['id'])){
    echo file_get_contents("data/".$_GET['id']);
  } else {
    echo "Hello, PHP";
  }
}
function print_list(){
  $list = scandir('./data');
  $i = 0;
  while($i < count($list)){
    if($list[$i] != '.'){
      if($list[$i] != '..') {
        echo "<li><a href=\"index.php?id=$list[$i]\">$list[$i]</a></li>\n";
      }
    }
    $i = $i + 1;
  }
}
?>

 

lib 이라는 디렉토리를 만들고 그 안에 print.php 라는 파일을 만들어준다

 

그리고 그 안에 이 겹치는 부분의 코드를 입력해준다

 

index.php create.php update.php 파일에 겹치는 부분을 지우고

 

<?php
require('lib/print.php');
?>

 이것을 입력해준다

 

보여지는 것과 관련된 view 라는 디렉토리를 만들어 준다

 

view 디렉토리 안에 bottom 이라는 파일을 만들어주고

 

</body>
</html>

이 중복되는 코드들을 집어넣어준다

 

이도 똑같이 index create update 에

 

    <?php
    require('view/bottom.php');
     ?>

입력해준다

 

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
      <?php
      print_title();
      ?>
    </title>
  </head>
  <body>
    <h1><a href="index.php">WEB</a></h1>
    <ol>
      <?php
      print_list();
      ?>
    </ol>

이 부분도 겹친다 이것은 top.php라고 view 디렉토리 안에 만들어주고

 

똑같이

 

<?php
require('view/top.php');
 ?>

해주면 된다

 

top.php 파일에서 print_title(); 이 어떤 것을 가리키는지 정확히 알지 못하므로

 

lib디렉토리에서 print.php파일을 모듈로 불러와주자

 

<?php
require('lib/print.php');
 ?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
      <?php
      print_title();
      ?>
    </title>
  </head>
  <body>
    <h1><a href="index.php">WEB</a></h1>
    <ol>
      <?php
      print_list();
      ?>
    </ol>

 

이렇게 하면

 

Cannot redeclare print_title() 즉 중복되었다고 오류가 뜬다

 

왜냐하면 index.php에

 

<?php
require('lib/print.php');
require('view/top.php');
?>

print.php를 불러오고 또 top.php 또한 print.php를 불러오므로 중복 오류가 뜬 것이다

 

이때는

 

require_once 를 써주자

 

중복되게 쓰지 못하게 하고 한번만 쓰게 해준다

'휴지통 > PHP' 카테고리의 다른 글

공부(10)  (0) 2021.09.07
공부(8)  (0) 2021.09.07
공부(7)  (0) 2021.09.07
공부(6)  (0) 2021.09.06
공부(5)  (0) 2021.09.06

글생성

 

create.php 파일을 만들어 준다

 

<?php
function print_title(){
  if(isset($_GET['id'])){
    echo $_GET['id'];
  } else{
    echo "Welcome";
  }
}
function print_description(){
  if(isset($_GET['id'])){
    echo file_get_contents("data/".$_GET['id']);
  } else {
    echo "Hello, PHP";
  }
}
function print_list(){
  $list = scandir('./data');
  $i = 0;
  while($i < count($list)){
    if($list[$i] != '.'){
      if($list[$i] != '..') {
        echo "<li><a href=\"index.php?id=$list[$i]\">$list[$i]</a></li>\n";
      }
    }
    $i = $i + 1;
  }
}
?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
      <?php
      print_title();
      ?>
    </title>
  </head>
  <body>
    <h1><a href="index.php">WEB</a></h1>
    <ol>
      <?php
      print_list();
      ?>
    </ol>
    <a href="create.php">create</a>
    <form action="create_process.php" method="post">
      <p>
        <input type="text" name="title" placeholder="Title">
      </p>
      <p>
        <textarea name="description"
        placeholder="Description"></textarea>
      </p>
      <p>
        <input type="submit">
      </p>
    </form>
  </body>
</html>

 

create에서 제출버튼을 누르면 create_process.php로 링크가 옮겨지고 post방식으로 전송한다

 

이제 create_process.php 파일을 만들어보자

 

<?php
file_put_contents('data/'.$_POST['title'], $_POST['description']);
header('Location: /index.php?id='.$_POST['title']);
?>

파일을 입력받은 제목 본문으로 만들어주고

 

만들게되면 주소를 그 파일의 제목값으로 보내버린다

 

글수정

 

    <?php if(isset($_GET['id']))  { ?>
    <a href="update.php?id=<?php echo $_GET['id']; ?>">update</a>
    <?php } ?>

업데이트는 어떤 자료를 클릭했을 때 나와야 하므로 if문으로 id값이 존재할 때 띄우도록 하였다

 

이제 업데이트 버튼을 누르면 update.php?id=id값으로 이동할 것이다

 

<?php
function print_title(){
  if(isset($_GET['id'])){
    echo $_GET['id'];
  } else{
    echo "Welcome";
  }
}
function print_description(){
  if(isset($_GET['id'])){
    echo file_get_contents("data/".$_GET['id']);
  } else {
    echo "Hello, PHP";
  }
}
function print_list(){
  $list = scandir('./data');
  $i = 0;
  while($i < count($list)){
    if($list[$i] != '.'){
      if($list[$i] != '..') {
        echo "<li><a href=\"index.php?id=$list[$i]\">$list[$i]</a></li>\n";
      }
    }
    $i = $i + 1;
  }
}
?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
      <?php
      print_title();
      ?>
    </title>
  </head>
  <body>
    <h1><a href="index.php">WEB</a></h1>
    <ol>
      <?php
      print_list();
      ?>
    </ol>
    <a href="create.php">create</a>
    <?php if(isset($_GET['id']))  { ?>
    <a href="update.php?id=<?= $_GET['id']; ?>">update</a>
    <?php } ?>

     <form action="update_process.php" method="post">
       <input type="hidden" name="old_title" value="<?=$_GET['id']?>">
       <p>
         <input type="text" name="title" placeholder="Title" value="<?php print_title(); ?>">
       </p>
       <p>
         <textarea name="description"
         placeholder="Description"><?php print_description(); ?></textarea>
       </p>
       <p>
         <input type="submit">
       </p>
     </form>
  </body>
</html>

update를 누를 시

 

제목과 본문이 그대로 수정할 수 있게 값이 입력되어져 있을 것이다

 

그리고 rename을 위해서 hidden타입으로 옛 제목을 만들어주고

 

짧은태그로 <?= 를 사용해주었다 이는 <?php echo 와 같은 뜻이다

 

update_process를 보자

 

<?php
  rename('data/'.$_POST['old_title'], 'data/'.$_POST['title']);
  file_put_contents('data/'.$_POST['title'], $_POST['description']);
  header('Location: /index.php?id='.$_POST['title']);
?>

rename을 통해서 이름을 바꾸어주고

 

파일을 만들어주고

 

그 아이디에 맞는 주소로 이동하게 된다

 

'휴지통 > PHP' 카테고리의 다른 글

공부(10)  (0) 2021.09.07
공부(9)  (0) 2021.09.07
공부(7)  (0) 2021.09.07
공부(6)  (0) 2021.09.06
공부(5)  (0) 2021.09.06

form과 POST

 

form.html 파일을 만들고

 

<!DOCTYPE html>
<html>
  <body>
    <form action="form.php">
      <p><input type="text" name="title" placeholder="Title"></p>
      <p><textarea name="description"></textarea></p>
      <p><input type="submit"></p>
    </form>
  </body>
</html>

위와 같은 코드를 입력해준다

 

이 코드는 제목과 본문을 입력받아 제출버튼을 누르면 form.php로 전송하는 코드이다

 

이제 form.php 코드를 만들어보자

<?php
echo "<p>title : ".$_GET['title']."</p>";
echo "<p>description : ".$_GET['description']."</p>";
?>

title값에는 title값을 description값에는 description값을 받아와주자

 

그러면 입력된 값들이 출력됨을 알 수 있다

 

하지만 이대로 하게되면 url에 내가 보내는 정보들이 다 노출되기 때문에 좋지 못하다

 

그래서 form 형식을 post방식으로 할 것이다

 

    <form action="form.php" method="post">

form 부분을 이렇게 method = "post"로 해주고

 

<?php
file_put_contents('data/'.$_POST['title'], $_POST['description']);
echo "<p>title : ".$_POST['title']."</p>";
echo "<p>description : ".$_POST['description']."</p>";
?>

이렇게 $_GET을 $_POST로 해주면 정상적으로 출력이 된다

'휴지통 > PHP' 카테고리의 다른 글

공부(9)  (0) 2021.09.07
공부(8)  (0) 2021.09.07
공부(6)  (0) 2021.09.06
공부(5)  (0) 2021.09.06
공부(4)  (0) 2021.09.06

+ Recent posts