데이터베이스

- 누구나 쉽게 데이터를 정리정돈할 수 있는 전문적인 소프트웨어

- 데이터를 표의 형태로 정리정돈할 수 있고 정렬 검색과 같은 작업을 빠르고 편리하고 안전하게 할 수 있다.

- MySQL, Oracle, SQL Server, PostgreSQL, DB2, Access 는 관계형 데이터베이스를 위한 기술들이다.

 

MySQL 구조

1) 표

2) 스키마 : 서로 연관된 표(데이터)들을 그룹핑하는 폴더

3) 데이터베이스 서버

 

서버 접속

1) cmd창을 켠다

2) cd명령어를 통해 mysql 위치로 이동

3) mysql -uroot -p 작성

 

스키마의 사용

- 데이터베이스 생성, 삭제, 확인, 사용

CREATE DATABASE 이름; //생성
DROP DATABASE 이름; //삭제
SHOW DATABASES; //데이터베이스 확인
USE 이름; // 해당 이름의 스키마에 있는 표를 대상으로 명령을 실행

 

SQL과 테이블의 구조

SQL(Structured Query Language) : 관계형 데이터베이스 카테고리에 속한 제품들이 공통적으로 데이터베이스 서버를 제어할 때 사용하는 표준화된 언어

 

 

테이블의 생성

CREATE TABLE topic(
      id INT(11) NOT NULL AUTO_INCREMENT,
      title VARCHAR(100) NOT NULL,
      description TEXT NULL,
      created DATETIME NOT NULL,
      author VARCHAR(30) NULL,
      profile VARCHAR(30) NULL,
      PRIMARY KEY(id));

not null : 공백을 허용하지 않겠다

null : 공백을 허용하겠다

AUTO_INCREMENT : 자동으로 1씩 증가시켜 중복되지 않는 식별자를 갖게된다

VARCHAR(100) : 100글자까지는 입력 가능, 그 이상은 지워버린다

PRIMARY KEY(id) : id값은 중복되지 않는다

dDd생성된 topic TABLE

 

CRUD

Create Read Update Delete : 데이터베이스가 가지고 있는 중요한 네가지 작업

 

INSERT

 INSERT INTO 테이블이름(필드이름1, 필드이름2, 필드이름3, ...) VALUES (데이터값1, 데이터값2, 데이터값3, ...);

 

SELECT

- 추가한 데이터 확인하기(모든 필드)

SELECT * FROM 테이블이름

 

- 원하는 필드만 데이터 확인하기

SELECT 필드이름1, 필드이름2, ..., 필드이름n FROM 테이블이름;

 

- 옵션 : 특정 값을 가지는 행을 출력하기

SELECT 필드이름1, 필드이름2, ..., 필드이름n FROM 테이블이름 WHERE 필드이름='특정 값';

 

- 옵션 : 정렬하기

SELECT 필드이름1, 필드이름2, ..., 필드이름n FROM 테이블이름 WHERE 필드이름='특정 값' ORDER BY 필드이름 정렬방법;

정렬 방법 : ASC(오름차순), DESC(내림차순)

 

- 옵션 : 개수 제한 두기

SELECT 필드이름1, 필드이름2, ..., 필드이름n FROM 테이블이름 WHERE 필드이름='특정 값' ORDER BY 필드이름 정렬방법 LIMIT 개수;

 

UPDATE

UPDATE 테이블이름 SET 필드이름1=데이터값1, 필드이름2=데이터값2, ... WHERE 필드이름=데이터값;

수정 후

cf) WHERE문을 작성하지 않으면 모든 값이 바뀐다.

 

DELETE

DELETE FROM 테이블이름 WHERE 필드이름=데이터값;

cf) WHERE문을 작성하지 않으면 모든 값이 삭제된다.

 

관계형데이터베이스의 필요성

- 데이터의 중복 제거

- 참조테이블

장점 : 중복 제거 가능, 일괄적으로 데이터의 수정 가능, 같은 이름의 값이라도 구분 가능

단점 : 직관적으로 데이터를 볼 수 없음

=> 데이터를 별도의 테이블로 보관함으로써 중복을 발생시키지 않는 참조테이블의 장점 + 실제로 데이터를 하나의 테이블로 볼 수 있는 기존테이블의 장점 = MySQL을 이용하면 가능해짐(저장 : 분산/ 보여줄 때 : 합쳐서)

 

테이블 분리하기

- 테이블 이름 변경

RENAME TABLE 테이블이름 TO 변경할 테이블이름;

 

 

https://opentutorials.org/module/3300/19521에서 가져온 코드

--
-- Table structure for table `author`
--
 
 
CREATE TABLE `author` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `profile` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
);
 
--
-- Dumping data for table `author`
--
 
INSERT INTO `author` VALUES (1,'egoing','developer');
INSERT INTO `author` VALUES (2,'duru','database administrator');
INSERT INTO `author` VALUES (3,'taeho','data scientist, developer');
 
--
-- Table structure for table `topic`
--
 
CREATE TABLE `topic` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(30) NOT NULL,
  `description` text,
  `created` datetime NOT NULL,
  `author_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
);
 
--
-- Dumping data for table `topic`
--
 
INSERT INTO `topic` VALUES (1,'MySQL','MySQL is...','2018-01-01 12:10:11',1);
INSERT INTO `topic` VALUES (2,'Oracle','Oracle is ...','2018-01-03 13:01:10',1);
INSERT INTO `topic` VALUES (3,'SQL Server','SQL Server is ...','2018-01-20 11:01:10',2);
INSERT INTO `topic` VALUES (4,'PostgreSQL','PostgreSQL is ...','2018-01-23 01:03:03',3);
INSERT INTO `topic` VALUES (5,'MongoDB','MongoDB is ...','2018-01-30 12:31:03',1);

 

 

테이블을 author, topic 2개로 분리하였다

 

JOIN

SELECT * FROM 테이블1 LEFT JOIN 테이블2 ON 테이블1.필드a = 테이블2.필드b;

테이블1의 필드a와 테이블2의 필드b가 같은 것을 의미할 때 이 둘을 기준으로 두 테이블을 join시킨다.

모든 필드 보이도록 지정
정해진 필드만 보여지도록 지정

 

인터넷과 데이터베이스

Internet

- 인터넷을 이용하기 위해서 필요한 최소한의 컴퓨터 : 2대

- 각자 흩어져있는 컴퓨터들이 인터넷으로 연결되면서 컴퓨터들 간의 사회가 만들어짐 => 한 대의 컴퓨터가 가지고 있는 한계를 초월함

- 한 대의 컴퓨터는 다른 컴퓨터에게 정보를 요청, 다른 컴퓨터는 요청한 정보를 응답

 

ex) 웹

웹이 동작하려면 인터넷이 필요하고, 인터넷 위에서 동작하기 때문에 두 대의 컴퓨터가 필요함.

한 대의 컴퓨터에는 웹 브라우저가 설치, 웹 브라우저에 주소를 입력함

-> 웹 브라우저가 설치된 컴퓨터가 요청한 정보를 요청한 컴퓨터에게 전송

-> 정보를 받아 웹브라우저에 표시(응답)

 

요청하는 쪽 : Client ex) 웹 클라이언트, 게임 클라이언트, 채팅 클라이언트

응답하는 쪽 : Server ex) 웹 서버, 게임 서버, 채팅 서버

 

MySQL 설치하면 동시에 2개 설치 (데이터베이스 클라이언트 & 데이터베이스 서버)

- 데이터베이스 클라이언트를 통해 데이터베이스 서버에 접속

- 데이터베이스 서버 : 데이터 저장

 

데이터베이스 서버를 직접 다룰 수 없음 -> 데이터베이스 클라이언트(ex) MySQL)를 통해야 다룰 수 있음 

 

MySQL Workbench

- GUI 기반의 MySQL Client

코드 입력 후 번개 표시 클릭하면 표가 나온다

 

- 새로운 스키마 생성

이름 지정 후 apply 버튼을 누른다.

 

apply 버튼 누르고 finish 버튼을 누른다.

 

workbench라는 데이터베이스가 추가된 것을 확인할 수 있다.

 

- 새로운 테이블 생성

데이터 작성 후 apply 버튼을 누른다.

sql문이 나오는 것을 확인할 수 있다.

 

=> MySQL 모니터, MySQL Workbench 등 모든 클라이언트들은 MySQL 서버에 전송함으로써 데이터베이스 서버를 제어한다.

'Web Hacking > WEB Hacking 기초' 카테고리의 다른 글

[SISS] XSS Game 05, 06  (0) 2022.01.22
[SISS] XSS Game 03, 04  (0) 2022.01.10
[SISS] XSS Game 01, 02  (0) 2022.01.03
[SISS] XSS 공부  (0) 2021.12.31
[SISS] 생활코딩 WEB2-PHP 정리  (0) 2021.12.28

Level 01


alert 창을 띄우기 위해 <script>구문을 사용하여 <script>alert();</script>라고 입력해주었다.


입력하였더니 alert가 뜨고 다음 단계로 넘어갈 수 있었다.


Level 02

<script>alert();</script>를 입력해주어도 아무 변화가 일어나지 않는다.

onerror를 검색해보니 이미지 로드 실패 시 실행되는 img 태그의 속성임을 알 수 있었다.

img가 로드되지 않게 하고 onerror 속성을 이용해 경고창을 띄우기 위해 <img src="/" onerror="alert()">라고 작성해주었다.

 

입력하였더니 alert가 뜨고 다음 단계로 넘어갈 수 있었다.

'Web Hacking > WEB Hacking 기초' 카테고리의 다른 글

[SISS] XSS Game 05, 06  (0) 2022.01.22
[SISS] XSS Game 03, 04  (0) 2022.01.10
[SISS] 생활코딩 DATABASE-MySQL 정리  (0) 2022.01.08
[SISS] XSS 공부  (0) 2021.12.31
[SISS] 생활코딩 WEB2-PHP 정리  (0) 2021.12.28

XSS 공격

 

- 웹 상에서 가장 기초적인 취약점 공격 방법의 일종으로 악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법

- 공격 성공 -> 사이트에 접속한 사용자는 삽입된 코드 실행 -> 의도치 않은 행동을 수행시킴 or 쿠키나 세션 토큰 등의 민감한 정보 탈취

- 자바스크립트 사용하는 경우 많음

 

종류

- 저장 XSS 공격 (Stored XSS) -> 보안상 가장 위협

악의적인 스크립트코드가 웹에 입력되면서 DB에 저장된다. 불특정 다수가 공격자의 게시물에 접근하면 지속적으로 악의적인 스크립트가 실행되어 위협이 큰 편이다.

ex) 랜섬웨어

 

<공격 단계>

  1. 게시판, 프로필, 댓글 등에 악성 스크립트를 삽입
  2. 사용자가 사이트를 방문하여 저장되어 있는 페이지에 정보를 요청할 때(게시판 글 읽기 등)
  3. 서버는 악성 스크립트를 사용자에게 전달하여 사용자 브라우저에서 스크립트가 실행되면서 공격

 

- 반사 XSS 공격 (Reflected XSS)

웹페이지 URL에 존재하는 파라미터의 악의적인 스크립트 코드를 입력하여 사용자가 URL을 클릭하면 그 코드가 실행되게 하는 공격이다.

 

<공격 단계>

  1. 취약점이 있는 A사이트를 발견
  2. 민감한 정보를 획득할 수 있는 공격용 악성 URL을 생성
  3. 공격자는 이 URL을 이메일, SMS 등에 포함하여 배포하고 클릭 유도
  4. 피해자가 URL을 클릭하면, 바로 공격 스크립트가 피해자로 반사되어 A 사이트에 관련된 민감한 정보(ID/패스워드, 세션 정보)를 공격자에게 전송

- DOM 기반 XSS 공격 ( DOM Based XSS)

DOM 환경에서 URL을 해 사용자의 브라우저를 공격하는 것이다.

 

DOM : W3C 표준으로 HTML 및 XML 문서에 접근방법을 표준으로 정의하는 문서객체모델

W3C에서는 DOM을 '프로그램 및 스크립트가 문서의 컨텐츠, 구조 및 형식을 동적으로 접근 및 업데이트할 수 있도록 하는 언어 중립적인 인터페이스다'라고 정의되어 있다. DOM은 HTML문서를 계층적으로 보면서 컨텐츠를 동적으로 변경할 수 있다.

'Web Hacking > WEB Hacking 기초' 카테고리의 다른 글

[SISS] XSS Game 05, 06  (0) 2022.01.22
[SISS] XSS Game 03, 04  (0) 2022.01.10
[SISS] 생활코딩 DATABASE-MySQL 정리  (0) 2022.01.08
[SISS] XSS Game 01, 02  (0) 2022.01.03
[SISS] 생활코딩 WEB2-PHP 정리  (0) 2021.12.28

PHP의 원리

> .html

- 웹브라우저에서 html파일을 요청 -> 웹서버가 확장자를 확인, 자신이 처리할 수 있는 html임을 판단 -> htdocs 디렉토리에서 읽고 웹브라우저에 전송

 

> .php

- 웹브라우저에서 php파일을 요청 -> 웹서버가 확장자를 확인, 자신이 처리할 수 없기 때문에 PHP에게 파일에 대한 처리를 위임 -> PHP가 htdocs 디렉토리에서 읽고 PHP 문법에 따라 해석하고 html파일을 생산 -> 그 html을 웹서버가 웹브라우저에게 전송

 

<? php //php 코드 시작
	echo date('Y-m-d H:i:s')
?> //php 코드 끝

- 동적으로 웹페이지를 생성할 수 있음 (html은 정적)

 

PHP의 데이터 타입

> 숫자 표현

<? php
	echo 1; //1출력
    print(1); //1출력
    echo 1+1; //2출력
?>

- 산술 연산자 : +, -, *, /

 

> 문자 표현

<? php
	'Hello World' // error
    
    echo 'Hello world'; // single quotes
    echo "Hello world"; // double quotes
    
    echo "Hello 'w'orld"; // Hello 'w'orld 출력
    echo "Hello "w"orld"; // error
    
    //concatenation operator
    echo "Hello"."world"; // .으로 이어진 좌항과 우항을 연결해서 하나의 문자열을 만들어냄
    
    //strlen 함수
    echo strlen("Hello world"); // 문자열 길이인 11출력
?>

- 문자열 결합 연산자 : .

 

PHP의 변수

<?php
    $a=10; // 변수 a에 10 할당
    echo $a+1; // 11출력
?>
<?php
    $name ="이름";
    echo "name 출력".$name; // $name에 '이름'이라고 출력
?>

- 변수 선언 : $변수이름 = 값;

 

URL 파라미터

안녕하세요. <?php echo $_GET[‘name’]; ?>님

- 주소가 바뀜에 따라 name에 들어가는 문자가 달라짐

 

함수

> strlen, nl2br 함수

<?php 
$str="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
 tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 
 quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 
 
 consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse 
 cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non 
 proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
 echo $str;
 echo strlen($str); 
 echo nl2br($str); 
?>

 

- strlen 함수 : 문자열 길이 확인 함수 
- nl2br 함수 : 자동으로 줄바꿈을 해주는 함수

 

> file_get_contents 함수

<!DOCTYPE html>
<html>
 <head>
   <meta charset="utf-8">
   <title></title>
 </head>
 <body>
   <h1>WEB</h1>
   <ol>
     <li><a href="index.php?id=HTML">HTML</a></li>
     <li><a href="index.php?id=CSS">CSS</a></li>
     <li><a href="index.php?id=Java">Java</a></li>
   </ol>
   <h2>
     <?php
     echo $_GET['id'];
     ?>
   </h2>
    <?php
      echo file_get_contents("data/".$_GET['id']); 
    ?>
 </body>
</html>

- file_get_contents 함수 :  문자열로 전체 파일을 읽어주는 함수

여기서는 id로 들어오는 값을 경로로 전환해 주고 data파일 내에 있는 해당 파일을 찾아서 표현해주는 역할을 하였다.

 

Boolean과 비교 연산자

<?php
  var_dump(11); // 출력 : int(11)
  var_dump('11'); // 출력 : string(2) "11"
  var_dump(1==2); // 출력 : bool(false)
  var_dump(1<2); // 출력 : bool(true)
?>

- var_dump 함수 : 괄호 내 값의 데이터 형식과 함께 같이 출력시켜주는 함수 (주로 개발할 때 쓰임)

 

제어문 - 조건문과 반복문

> 조건문

<?php
  echo '1<br>';
  if(true){
      echo '2<br>'
  }
  else{
      echo '3<br>'
  }
?>

true일 경우, 1과 2가 출력되고 false일 경우, 1과 3이 출력된다.

<!DOCTYPE html>
<html>
 <head>
   <meta charset="utf-8">
   <title></title>
 </head>
 <body>
   <h1><a href="index.php">WEB</a></h1>
   <ol>
     <li><a href="index.php?id=HTML">HTML</a></li>
     <li><a href="index.php?id=CSS">CSS</a></li>
     <li><a href="index.php?id=Java">Java</a></li>
   </ol>
   <h2>
     <?php
     	if(isset($_GET['id'])){ //id값이 있는지
        	echo $_GET['id'];
        }
        else{
        	echo "Welcome";
        }
     ?>
   </h2>
    <?php
    	if(isset($_GET['id'])){
        	echo $_GET['id'];echo file_get_contents("data/".$_GET['id']); 
        else{
        	echo "Hello, PHP";
        }
    ?>
 </body>
</html>

- isset 함수 : 해당 값이 존재하는 지를 판별하는 함수

 

> 반복문

<?php
    echo '1<br>';
    $i=0;
    while($i<3){
    	echo '2<br>';
        $i=$i+1;
    }
?>

1 출력 후  $i가 0, 1, 2일 때 2가 총 세 번 출력된다. 

 

> 배열

 

<?php
	$coworkers = array('egoing', 'leezche', 'duru', 'taeho');
    echo $coworkers[1].'<br>'; // 출력 : leezche
    echo $coworkers[3].'<br>'; // 출력 : taeho 
    var_dump(count($coworkers)); // 출력 : int(4)
    array_push($coworkers, 'graphittie'); // 배열에 원소 추가
?>

 

> 활용

<!DOCTYPE html>
<html>
 <head>
   <meta charset="utf-8">
   <title></title>
 </head>
 <body>
   <h1><a href="index.php">WEB</a></h1>
   <ol>
   	<?php
    	$list = scandir('./data'); // data 하위 파일들 읽어옴
        
        $i = 0;
        while($i < count($list)) // list 개수만큼 반복
        {
        	if($list[$i] != '.'){ // 현재디렉토리 제외
            	if($list[$i] != '..'){ //부모디렉도리 제외
                  echo "<li><a href=\"index.php?id=$list[$i]\">$list[$i]</a></li>\n";
                }
            }
            $i = $i + 1;
        }
     ?>
   </ol>
   <h2>
     <?php
     	if(isset($_GET['id'])){ //id값이 있는지
        	echo $_GET['id'];
        }
        else{
        	echo "Welcome";
        }
     ?>
   </h2>
    <?php
    	if(isset($_GET['id'])){
        	echo $_GET['id'];echo file_get_contents("data/".$_GET['id']); 
        else{
        	echo "Hello, PHP";
        }
    ?>
 </body>
</html>

이 코드를 이용하면(<ol>태그 부분) data디렉토리 아래에 새로운 파일을 추가해도(데이터가 달라져도) 자동으로 웹에 추가된다.

 

함수

<?php
    function basic(){
    	print("abc1<br>");
        print("abc2<br>");
    }
    basic(); // 함수 내 코드 실행
    
    function sum($left, $right){
      print($left+$right);
      print("<br>");
    }
    sum(2,4); // 출력 : 6
    sum(4,6); // 출력 : 10
?>

 

> 활용

<? php
    function print_title(){
   	 	if(isset($_GET['id'])){ //id값이 있는지
        	echo $_GET['id'];
        }
        else{
        	echo "Welcome";
        }
    }
    function print_description(){
    	if(isset($_GET['id'])){
        	echo $_GET['id'];echo file_get_contents("data/".$_GET['id']); 
        else{
        	echo "Hello, PHP";
        }
    }
    function print_list(){
    	$list = scandir('./data'); // data 하위 파일들 읽어옴
        
        $i = 0;
        while($i < count($list)) // 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>
   	print_title();
   </title>
 </head>
 <body>
   <h1><a href="index.php">WEB</a></h1>
   <ol>
     <?php
    	print_list();
     ?>
   </ol>
   <h2>
     print_title();
   </h2>
    <?php
    	print_description();
    ?>
 </body>
</html>

함수로 코드를 정리하였다.

 

Form과 POST

<!doctype html>
<html>
  <body>
    <form action="form.php" method="post">
      <p><input type="text" name="title" placeholder="Title"></p>
      <p><textarea name="description"></textarea></p>
      <p><input type="submit"></p>
    </form>
  </body>
</html>
<?php
  file_put_contents('data/'.$_POST['title'], $_POST['description']);
?>

URL을 통해 데이터를 전송하는 방식은 사용자가 서버로 데이터를 보낼 때 쓰면 안된다. 데이터를 서버쪽으로 전송할 때, 주소의 title 혹은 파라미터 정보가 포함되어 있으면 사용자들이 자신이 원하지 않았는데 글이 써지는 등의 일이 발생할 수 있기 때문이다. -> 해결 방법 : form 태그에 method를 post로 지정

 

글 생성, 수정, 삭제

//index.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>
    <?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>

update의 경우 해당 항목을 클릭했을 때만 수정항목을 보이도록 하기위해 조건문에 isset을 이용해 인자로 들어오는 값이 있는지를 확인해준다.

 

//create, update.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>
    <?php if(isset($_GET['id'])) { ?>
      <a href="update.php?id=<?=$_GET['id']?>">update</a>
    <?php } ?>
    <h2> //수정 폼
     <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>

삭제는 form을 거칠 필요 없다.

//create_process.php

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

header를 이용해서 사용자를 다른페이지로 보낼 수 있다. 

//update_process.php

<?php
rename('data/'.$_POST['old_title'], 'data/'.$_POST['title']); //파일명 수정
file_put_contents('data/'.$_POST['title'], $_POST['description']); //내용 수정
header('Location: /index.php?id='.$_POST['title']);
?>

submit했을 때 id가 old_title로 전송된다.

//delete_process.php

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

unlink를 통해 내용을 삭제할 수 있다.

 

파일의 모듈화 - require

- 중복의 제거

재사용할만한 코드를 정리정돈하여 사용

<?php
require('lib/print.php'); //재사용할만한 코드 정리
?>

-> 모든 페이지를 통합적으로 관리할 수 있다.

 

cf) 한번 만들어진 함수는 다시 재정의할 수 없다. -> error

-> 해결방법 : require을 require_once로 변경

 

보안 XSS

> Cross Site Scripting : 웹사이트에 스크립트 태그를 주입하는 것

<script>
location.href="https://opentutorials.org/course/";
</script>

위와 같은 코드를 작성하여 버튼을 누르면 아예 다른 웹페이지로 넘어가게 된다.

 

> 문제점

- 로그인을 대신 하는 경우 발생

- 글을 지우는 경우 발생

- 정보 유출 경우 발생

 

-> 사용자가 입력한 정보는 모두 불신해야 한다.

 

> 예방 방법

<?php
echo htmlspecialchars('<script>alert("babo");</script>');
?>

'<'를 특수한 코드로 바꾸어버려 그 자바스크립트를 인식하지 못하도록 한다.

 

보안 파일 경로 보호

 

<?php
function print_title(){
  if(isset($_GET['id'])){
    echo htmlspecialchars($_GET['id']);
  } else {
    echo "Welcome";
  }
}
function print_description(){
  if(isset($_GET['id'])){
    $basename = basename($_GET['id']);
    echo htmlspecialchars(file_get_contents("data/".$basename));
  } 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;
  }
}
?>

- basename 함수 : 파일의 경로에서 파일명을 추출해주는 함수

이를 이용해 부모디렉토리로 가는 등의 악용을 막을 수 있다.

 

'Web Hacking > WEB Hacking 기초' 카테고리의 다른 글

[SISS] XSS Game 05, 06  (0) 2022.01.22
[SISS] XSS Game 03, 04  (0) 2022.01.10
[SISS] 생활코딩 DATABASE-MySQL 정리  (0) 2022.01.08
[SISS] XSS Game 01, 02  (0) 2022.01.03
[SISS] XSS 공부  (0) 2021.12.31

+ Recent posts