보안을 강화한 시큐어코딩 웹게시판 (windows)

보안을 강화한 시큐어 코딩

law and security 2024. 9. 6. 16:01

(보안취약_보안강화 게시판)

게시판 소스 리스트:

1)   dbconn.php     :데이터베이스 연결

2)   register.php    : 회원가입

3)   login.php       : 로그인 화면

4)   logout.php     :로그 아웃

5)   notice_list.php   :게시판 리스트

6)   notice_add_page.php   : 게시판 글 추가하는 화면

7)   notice_add.php     : 게시판 글 추가하는 부분을 데이터베이스에 저장

8)   notice_edit_page.php  : 게시판 글 수정

9)   notice_edit.php   : 게시판 글 수정을 데이터베이스에 반영

10)   delete.php  : 게시글 삭제

 

 

1)   dbconn2.php     :데이터베이스 연결

 

create table dbo.users(
	UserID char(10) NOt NULL PRIMARY kEY,
	Username nvarchar(5) NOT NULL,
	Password nvarchar(255) NOT NULL);
GO

create table dbo.Posts(
	PostID int IDENTITY(1,1) NOT NULL PRIMARY KEY,
	Title nvarchar(100) NULL,
	Content nvarchar(max) NULL,
	CreatedDate datetime NULL,
	UserID char(10) NULL FOREIGN KEY REFERENCES Users(UserID));
GO

select * FROM users;
select* FROM posts;

 

 

 

<HTML>에 wwwroot 속에 board2파일을 생성한 뒤 dbcon2.php파일을 생성한다. 아래와 같이 입력

 

<?php
//세션이 시작되지 않은 경우 세션을 시작합니다.
if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

//현재 스크립트 파일의 이름을 가져옵니다.

$current_file = basename($_SERVER['PHP_SELF']);

//현재 파일이 'login.php' 또는 'register.php'가 아닌 경우, 그리고 세션에 'UserID'가 설정되지 않는 경우
// 로그인 페이지로 리디렉션합니다.

if(($current_file!='login2.php'&&$current_file!='register2.php')&& !isset($_SESSION['UserID']))
{
	//사용자에게 로그인 필요 메시지를 표시합니다.
	echo "<script>alert('로그인이 필요합니다');</script>";
	//로그인 페이지로 이동합니다.
	echo "<script>location.herf='login2.php';</script>";
	exit; //스크립트 실행을 종료합니다.
}
?>

<?php
//데이터베이스 서버 주소를 설정합니다.(로컬 서버를 나타냅니다.)
//실제 서버 주소를 사용할 경우 주석을 해제하고 변경합니다. 
//$serverName="192.168.111.10";

$serverName="(local)"; //또는 "localhost"사용 가능
$database="testDB3";  //연결한 데이터베이스의 이름

//데이터베이스 인증에 사용할 사용자 이름과 비밀번호를 설정합니다. 

$uid="sa";  //사용자아이디
$pwd="p@ssw0rd";  //비밀번호

//데이터베이스 테이블 이름을 설정합니다.

$table="Posts";

//데이터베이스에 연결을 시도합니다.

try{
	 //PDO 객체를 생성하여 SQL Server에 연결합니다.
	$conn=new PDO("sqlsrv:server=$serverName;database=$database",$uid,$pwd);

	//오류 발생 시 예외를 발생시키도록 설정합니다.

	$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}  catch (PDOException $e){
	//데이터베이스 연결 오류가 발생한 경우 오류 메시지를 출력하고 스크립트를 종료합니다. 
	die("Error connecting to SQL Server");
}

?>

 

2)   register2.php    : 회원가입

 

<?php
//세션이 시작되지 않은 경우 세션을 시작합니다.
if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

//현재 스크립트 파일의 이름을 가져옵니다.

$current_file = basename($_SERVER['PHP_SELF']);

//현재 파일이 'login.php' 또는 'register.php'가 아닌 경우, 그리고 세션에 'UserID'가 설정되지 않는 경우
// 로그인 페이지로 리디렉션합니다.

if(($current_file!='login2.php'&&$current_file!='register2.php')&& !isset($_SESSION['UserID']))
{
	//사용자에게 로그인 필요 메시지를 표시합니다.
	echo "<script>alert('로그인이 필요합니다');</script>";
	//로그인 페이지로 이동합니다.
	echo "<script>location.herf='login2.php';</script>";
	exit; //스크립트 실행을 종료합니다.
}
?>

<?php
//데이터베이스 서버 주소를 설정합니다.(로컬 서버를 나타냅니다.)
//실제 서버 주소를 사용할 경우 주석을 해제하고 변경합니다. 
//$serverName="192.168.111.10";

$serverName="(local)"; //또는 "localhost"사용 가능
$database="testDB3";  //연결한 데이터베이스의 이름

//데이터베이스 인증에 사용할 사용자 이름과 비밀번호를 설정합니다. 

$uid="sa";  //사용자아이디
$pwd="p@ssw0rd";  //비밀번호

//데이터베이스 테이블 이름을 설정합니다.

$table="Posts";

//데이터베이스에 연결을 시도합니다.

try{
	 //PDO 객체를 생성하여 SQL Server에 연결합니다.
	$conn=new PDO("sqlsrv:server=$serverName;database=$database",$uid,$pwd);

	//오류 발생 시 예외를 발생시키도록 설정합니다.

	$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}  catch (PDOException $e){
	//데이터베이스 연결 오류가 발생한 경우 오류 메시지를 출력하고 스크립트를 종료합니다. 
	die("Error connecting to SQL Server");
}

?>

 

Prepared Statements 동작단계:

 

1.   쿼리 준비 (Prepare):

- 먼저 SQL 쿼리의 구조만 서버에 전달하고, 값은 나중에 바인딩할 수 있도록 플레이스홀더(예: ? 또는 명명된 플레이스홀더 :name)를 사용합니다.

- 이 과정에서 데이터베이스는 쿼리의 구조를 미리 컴파일하고 최적화합니다.

 

 

2.   값 바인딩 후 실행 (Execute):

- 쿼리 실행 시 바인딩된 값을 플레이스홀더에 채워 넣어 쿼리를 실행합니다.

 

 

 

 

 

 

 

 

 

 

 

3)   login2.php       : 로그인 화면

 

<?php
session_start();
include "dbconn2.php";

if($_SERVER['REQUEST_METHOD']==='POST'){
	$userid=$_POST['userid'];
	$password=$_POST['password'];

	try{
		//SQL쿼리 : 사용자 정보를 조회
		$sql = "SELECT * FROM Users WHERE UserID=:userid";
		$stmt=$conn->prepare($sql);  //쿼리 실행
		$stmt->bindParam(':userid',$userid);
		$stmt->execute(); //쿼리 실행 

		$user=$stmt->fetch(PDO::FETCH_ASSOC);

		//비밀번호가 일치하는지 확인

		if($user && password_verify($password,$user['Password'])){
			$_SESSION['UserID'] = $user['UserID'];  //세션에 사용자 ID저장
			$_SESSION['Username']=$user['Username'];  //세션에 사용자 이름 저장
			echo "<script>alert('로그인 성공');</script>";
			echo "<script>location.href='notice_list2.php';</script>";
			exit(); //리다이렉트 후 코드 실행 방지
		}
		else {
			echo "<script>alert('로그인 실패: 사용자 ID 또는 비밀번호가 잘못되었습니다.');</script>";
		}
	} catch (PDOException $e){
		//쿼리 실행 실패 시 오류 메시지 출력
		die("로그인 중 오류가 발생했습니다:".$e->getMessage());
	}
}
?>

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>로그인</title>
</head>
<body>
	<h2>로그인</h2>
	<form method="POST" action="login2.php">
		<label>사용자 ID : 
			<input type="text" name="userid">
		</label>
		<br>
		<label>비밀번호 :
			<input type="password" name="password" required>
		</label>
		<br>
		<button type="submit">로그인</button>
		<a href="register2.php">회원가입</a>
	</form>

</body>
</html>

 

 

보안강화(login.php)

 

해당 코드에서는 SQL 인젝션과 비밀번호 보안 문제가 있습니다. 이를 개선하기 위해 prepared statements를 사용하고, 비밀번호 해시를 검증하는 방법을 적용 합니다.

 

 

 

SQL 쿼리: prepared statement 사용하여 SQL 인젝션 방지

 

 

  • 비밀번호가 해시된 비밀번호와 일치하는지 확인
  • 쿼리 실행 실패 시 오류 메시지 출력

 

 

4)   logout2.php     :로그 아웃

 

<?php 
// 세션을 시작합니다. 세션이 이미 시작된 경우에는 아무 작업도 하지 않습니다.
session_start();

// 현재 세션을 종료하고, 세션 데이터를 삭제합니다.
session_destroy();

// 로그인 페이지로 리디렉션합니다. 헤더를 통해 클라이언트에게 새로운 URL로 이동하도록 지시합니다.
header('Location: login2.php');

// 스크립트 실행을 종료합니다. 헤더 호출 후 더 이상 코드가 실행되지 않도록 합니다.
exit;

?>

 

 

 

 

5)   notice_list2.php   :게시판 리스트

 

 

<?php

session_start();

if(!isset($_SESSION['UserID'])|| !isset($_SESSION['Username'])){
	echo "<script>alert('로그인이 필요합니다');</script>";
	echo "<script>location.href='login2.php';</script>";
	exit;
}
?>

<!DOCTYPE html>
<html lang="ko">
<head>
	<meta charset="UTF-8">
  <title>공지사항 리스트</title>
  <script type="text/javascript" src="https://www.google.com/jsapi"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

	<style>
       body{
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        p{
            margin: 0;
        }
        main{
            width: 100%;
            height: 100%;
        }
        .top_header{
            position: fixed;
            top: 0;
            width: 100%;
            background-color: black;
            color: white;
            padding: 20px 0;
            text-align: right;
            z-index: 9999;
        }
        .logout_btn{
            cursor: pointer;
            background-color: white;
            color: red;
            border: none;
            border-radius: 15px;
            outline: none;
            margin: 0 20px;
        }
        .excel_header{
            width: 80%;
            margin-top: calc(5% + 50px);
            margin-left: 10%;
            border: solid gray 1px;
            background-color: white;
            display: flex;
        }
        .excel_header div:nth-child(1){
            width: 40%;
            padding: 30px 20px;
	  
        }
        .excel_header h3{
            margin: 0;
          
            font-size: 20px;
        }
        .excel_header div:nth-child(2){
            width: 80%;
            text-align: right;
            margin-right: 50px;
            padding-top: 30px;
border-radius: 5px;
        }
        .excel_header div:nth-child(2) button{
            width: 100px;
            padding: 10px 0;
            border: solid black 1px;

            color: black;
            cursor:pointer;
        }
	.excel_header div:nth-child(2) button:hover{
    
	background-color: orange; 
        }

        .excel_wrapper{
            width: 80%;
            margin-left: 10%;
            margin-top: 3%;
        }
        .excel_wrapper table{
            width: 100%;
            border-collapse: separate;
            border-spacing: 0 10px;
        }
        .excel_wrapper thead,
        .excel_wrapper tbody{
            width: 100%;
        }
        .excel_wrapper th{
            padding: 5px 20px;
            border-bottom: solid black 2px;
            border-radius: 5px 5px 0 0;
            font-size: 20px;
            text-align: left;
        }
        .excel_wrapper td:nth-child(1){
            width: 5%;
        }
        .excel_wrapper td:nth-child(2){
            width: 20%;
        }
        .excel_wrapper td:nth-child(3){
            width: 45%;
            text-align: left;
        }
	.excel_wrapper td:nth-child(4){
            width: 20%;
            text-align: left;
        }
        .excel_wrapper td{
            padding: 7px 5px 17px 20px;
            border-bottom: solid gray 1px;
            font-size: 18px;
        }
        .excel_wrapper td:nth-child(3) button{
            padding: 5px 10px;
            border: solid gray 1px;
            border-radius: 5px;
            background-color: white;
            outline: none;
            cursor: pointer;
        }
        .excel_wrapper td:nth-child(3) button:hover{
            border: solid black 1px;
            background-color: orange;
        }
        /* 엑셀 버튼 */
        .excel_button{
            width: 100%;
            text-align: center;
            margin-top: 2%;
            /* margin-left: -2%; */
        }
        .excel_button button{
            padding: 15px;
            background-color: white;
            color: black;
            font-size: 15px;
            border: solid black 2px;
            cursor: pointer;
        }
        .excel_button button:nth-child(1),
        .excel_button button:nth-child(5){
            margin: 0 20px;
        }
        .excel_button button:nth-child(2),
        .excel_button button:nth-child(3),
        .excel_button button:nth-child(4){
            margin: 0 5px;
        }
        a{
            color: red;
        }
    </style>
</head>
<body>
	 <div class="top_header">
        <p><?php echo htmlspecialchars($_SESSION['Username'],ENT_QUOTES, 'UTF-8'); ?>님 <a href='logout2.php'><button class="logout_btn">로그아웃</button></a></p>
        
    </div>
  <div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
    <main>
    <div class="excel_header">
       <div>	
       		<h3>공지사항 관리</h3>
       	</div>

       <div>
       	<button onclick="location.href='notice_add2_page.php'">추가하기</button>
       </div>
   </div> <!-- excel_header -->
   <div class="excel_wrapper">
   	<table>
   		<thead>
   			<tr>
   				<th>번호</th>
   				<th>제목</th>
   				<th>내용</th>
   				<th>업데이트날짜</th>
   				<th>수정/삭제</th>
   			</tr>
   		</thead>
   	<tbody>
   		<?php
   		include "dbconn2.php";
   		$query="SELECT * FROM Posts ORDER BY PostID DESC";
		$stmt = $conn->query($query);
		while ( $row = $stmt->fetch( PDO::FETCH_ASSOC )){?>
			<tr>
				<td><?php echo htmlspecialchars($row['PostID'], ENT_QUOTES,'UTF-8');?></td>
				<td><?php echo htmlspecialchars($row['Title'], ENT_QUOTES,'UTF-8');?></td>
				<td><?php echo htmlspecialchars($row['Content'],ENT_QUOTES,"UTF-8");?></td>
				<td><?php echo htmlspecialchars($row['CreatedDate'],ENT_QUOTES,'UTF-8');?></td>
				<td>
				<?php if ($_SESSION['UserID'] == $row['UserID']) { ?>
					<a href="notice_edit2_page.php?PostID=<?php echo htmlspecialchars($row['PostID'], ENT_QUOTES, 'UTF-8'); ?>">수정/삭제</a>
				<?php } else { ?>
                    <span>수정/삭제 불가</span>
                <?php } ?> 
              </td>
          </tr>
      <?php }?>
     </tbody>
 </table>
</div>
</main>
</div>

</body>
</html>

 

 

 

 

 

 

 

 

6)   notice_add_page2.php   : 게시판 글 추가하는 화면

 

<?php
session_start();

if (!isset($_SESSION['UserID'])){
	echo "<script>alert('로그인이 필요합니다');</script>";
	echo"<script>location.href='login.php';</script>";
	exit;
}
?>

<!DOCTYPE html>
<html lang="ko">
<head>
	<script type="text/javascript" src="https://www.google.com/jsapi"></script>
	<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
	<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
	<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
	<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
	<script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width,initial-scale=1.0">
	<style>
		body{
			width: 100%;
			height: 100%;
			margin: 0;
			padding: 0;
			background-color: whitesmoke;
		}
		main{
			width: 100%;
			height: 100%;
		}
		.content_wrapper{
			width: 80%;
			margin-left: 20%;
		}
		.content_text{
			margin-top: 10%;
			font-size: 30px;
		}
		.add_title h5,
		.add_content h5{
			font-size: 30px;
		}
		.add_title input,
		.add_content input{
			font-size: 20px;
			width: 40%;
			padding: 20px 10px;
		}
		.button_content{
			margin-left: 35%;
			margin-top: 3%;
		}
		.button_content button:hover{
			background-color: orange;
		}
		.button_content button{
			width: 100px;
			padding: 15px 0;
			border: solid black 1px;
			border-radius: 5px;
			background-color: white;
		}
		.orange:focus{
			background-color: orange;
		}
	</style>
</head>
<body>
	<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
		<main>
			<div class="content_wrapper">
			<div class="content_text">
				<h2>공지사항 추가</h2>
			</div>
			<form action="notice_add2.php" method="POST" onsubmit="return vaildateForm()">
				<div class="add_title">
					<h5>제목</h5>
					<input type="text" maxlength="20" placeholder="20자까지 입력가능~!" class="orange" name="title">
				</div>
				<div class="add_content">
					<h5>내용</h5>
					<input type="text" maxlength="100" placeholder="100자까지 입력가능~!" value="" class="orange" name="content">
				</div>
				<div class="button_content">
					<button type="submit" id="add">추가하기</button>
				</div>
			</form>
		</div>   <!--content_wrapper --> 

		</main>
	</div>

</body>
</html>

 

 

1.   입력값 유효성 검사: 사용자가 입력한 값이 SQL 인젝션 및 XSS 공격에 노출되지 않도록 서버 측에서 입력값을 검증합니다.

2.   Prepared Statements 사용: SQL 쿼리를 실행할 때 사용자 입력이 직접 포함되지 않도록 준비된 명령문을 사용하여 SQL 인젝션을 방지합니다.

3.   HTML 엔티티 이스케이프: 출력 시 htmlspecialchars를 사용하여 XSS 공격을 방지합니다.

 

 

 

 

 

 

7)   notice_add2.php     : 게시판 글 추가하는 부분을 데이터베이스에 저장

 

 

<?php
session_start();

//로그인 여부 확인

if (!isset($_SESSION['UserID'])) {
    echo "<script>alert('로그인이 필요합니다');</script>";
    echo "<script>location.href='login2.php';</script>";
    exit;
}

?>

<?php

if($_SERVER['REQUEST_METHOD']!=='POST'){
    echo"<script>alert('잘못된 접근입니다.');</script>";
    echo "<script>location.href='notice_list2.php';</script>"; 
    exit;
}

date_default_timezone_set('Asia/Seoul');
$title= $_POST['title'];
$content= $_POST['content'];
$now= date('Y-m-d H:i:s');

if(empty($title)||empty($content)){
    echo"<script>alert('제목과 내용을 모두 입력해주세요');</script>";
    echo"<script>history.back();</script>";  //경고 메시지를 확인 후 , histroy.back()을 통해 이전 페이지로 돌아가도록 설정
    exit;
}

include "dbconn2.php"; // 데이터베이스 연결 설정 파일 포함

// 폼에서 전송된 데이터


try{
	//SQL쿼리 준비
	$query = "INSERT INTO Posts (Title, Content, CreatedDate, UserID) VALUES (:Title, :Content, :CreatedDate, :UserID)";
    $stmt = $conn->prepare($query); // 쿼리 준비

    // 바인드 파라미터 설정
    $stmt->bindParam(':Title', $title,PDO::PARAM_STR);
    $stmt->bindParam(':Content', $content,PDO::PARAM_STR);
    $stmt->bindParam(':CreatedDate', $now,PDO::PARAM_STR);
    $stmt->bindParam(':UserID', $_SESSION['UserID'],PDO::PARAM_STR);

     // 쿼리 실행
    $stmt->execute();

    // 성공 메시지 출력 후 페이지 이동
    echo "<script>alert('추가되었습니다');</script>";
    echo "<script>location.href='notice_list2.php';</script>";
} catch (PDOException $e) {
    // 오류 메시지 출력
    echo"<script>alert('데이터베이스 오류가 발생했습니다.');</script>";
      error_log("Database error: " . $e->getMessage()); //서버의 오류 로그에 기록
    echo"<script>history.back();</script>";
}

?>

 

 

→ 위 코드 추가

 

 

 

 

 

 

 

 

8)   notice_edit_page.php  : 게시판 글 수정

 

<?php
session_start();

if (!isset($_SESSION['UserID'])){
	echo"<script>alert('로그인이 필요합니다');</script>";
	echo"<script>location.href='login.php';</script>";
    exit;
}
?>

<!DOCTYPE html>
<html>
<head>
	<script type="text/javascript" src="https://www.google.com/jsapi"></script>
	<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>공지사항 수정</title>
 <style>
 	body{
 		width: 100%;
 		height: 100%;
 		margin: 0;
 		padding: 0;
 		background-color: whitesmoke;
 	}
 	main{
 		width: 80%;
 		margin-left: 20%;
 	}
 	.content_text{
 		margin-top: 10%;
 		font-size: 30px;
 	}
 	.edit_name h5,
 	.edit_content h5{
 		font-size: 30px;
 	}
 	.edit_title input,
 	.edit_content input{
 		font-size: 20px;
 		width: 40%;
 		padding: 20px 10px;
 	}
 	.orange:focus{
 		background-color: orange;
 	}
 	.button_content{
 		margin-left: 35%;
 		margin-top: 3%;
 	}
 	.button_content button{
 		width: 100px;
 		padding: 15px 0;
 		border: solid black 1px;
 		border-radius: 5px;
 		background-color: white;
 	}
 	.button_content button:hover{
	background-color: orange;
	}
    </style>
</head>

<body>
	<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
<main>
  <div class="content_wrapper">
    <div class="content_text">
	<h2>공지사항 수정</h2>
    </div>
    <?php  //해당 글번호의 행데이터값 읽어오기
	include "dbconn2.php";

if(isset($_GET['PostID']) && is_numeric($_GET['PostID'])){
	$PostID=$_GET['PostID'];
	$stmt=$conn->prepare("SELECT * FROM $table WHERE PostID=?");
	$stmt->execute([$PostID]);


if ($row=$stmt->fetch(PDO::FETCH_ASSOC)){
		$title = htmlspecialchars($row['Title'], ENT_QUOTES, 'UTF-8');
    $content = htmlspecialchars($row['Content'], ENT_QUOTES, 'UTF-8');
?>

  <form action="notice_edit2.php" method="POST" onsubmit="return confirmEdit()">
	
	<div class="edit_title">
	  <h5>제목</h5>
	  <input type="text" class="orange" value="<?=$title;?>" name="title">	
	</div> <!--제목 -->

	<div class="edit_content">
	  <h5>내용</h5>
	  <input type="text" class="orange" value="<?=$content;?>" name="content">
	  <input type="hidden" value="<?=$PostID;?>" name="PostID">
	 
	<div class="button_content">
	  <button id="submit">수정완료</button>
	  </div> <!--버튼-->
	

	<a href="delete2.php?PostID=<?=$PostID;?>">삭제</a>
	</div> <!--edit_content-->
  </form>

    <?php
  }else{
  	 echo "<p>해당 공지사항을 찾을 수 없습니다.</p>";}
  } else {
  	echo"<p>잘못된 요청입니다.</p>";
  }
  $conn=null;
  ?>

</div>
</main>

<script>
	function confirmEdit(){
		return confirm('수정 하시겠습니까?');
	}

</script>
</div><!--전체-->

</body>
</html>

 

 

 

 

 

 

 

 

 

 

 

 

9)   notice_edit2.php   : 게시판 글 수정을 데이터베이스에 반영

 

<?php
session_start();

//로그인 여부 확인

if (!isset($_SESSION['UserID'])) {
    echo "<script>alert('로그인이 필요합니다');</script>";
    echo "<script>location.href='login2.php';</script>";
    exit;
}

include "dbconn2.php"; // 데이터베이스 연결 설정 파일 포함

// 입력값 검증
if(isset($_POST['PostID'],$_POST['title'],$_POST['content'])&&is_numeric($_POST['PostID'])){
    $PostID=$_POST['PostID'];
    $title = $_POST['title'];
    $content = $_POST['content'];
    $now = date('Y-m-d H:i:s');

//데이터 필터링(XSS방지)

    $title = htmlspecialchars($title, ENT_QUOTES, 'UTF-8');
    $content = htmlspecialchars($content, ENT_QUOTES, 'UTF-8');

//Prepared Statement 사용
try {
    $stmt=$conn->prepare("UPDATE $table SET Title=?, Content=?, CreatedDate=? WHERE PostID=?");
    $stmt->execute([$title, $content, $now, $PostID]);

// 업데이트 성공 시
    if($stmt->rowCount()>0){
        echo"<script>alert('변경되었습니다');</script>";}
    else{
        echo"<script>alert('변경된 내용이 없습니다.');</script>";
    }
} catch(PDOException $e){
    // SQL 오류 처리
        echo "<script>alert('오류 발생: " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8') . "');</script>";
    }
    echo"<script>location.href='notice_list2.php';</script>";
} else{
       // 입력값이 없거나 유효하지 않은 경우
    echo "<script>alert('잘못된 요청입니다.');</script>";
    echo "<script>location.href='notice_list2.php';</script>";
}

$conn=null;

?>

 

 

 

10)   delete2.php  : 게시글 삭제

 

<?php
session_start();

if(!isset($_SESSION['UserID'])){
	echo"<script>alert('로그인이 필요합니다');</script>";
	echo"<script>location.href='login2.php';</script>";
	exit;
}

include "dbconn2.php";

// 입력값 검증
if (isset($_GET['PostID']) && is_numeric($_GET['PostID'])) {
    $PostID = $_GET['PostID'];

// Prepared Statement 사용

try{
	$stmt=$conn->prepare("DELETE FROM $table WHERE PostID=?");
	$stmt->execute([$PostID]);

//삭제 성공 시
	if ($stmt->rowCount() > 0) {
		echo"<script>alert('삭제되었습니다');</script>";
	}else{
		echo"<script>alert('삭제할 항목이 없습니다.');</script>";
	}
}catch(PDOException $e){
	//SQL오류처리
	echo "<script>alert('오류 발생:".htmlspecialchars($e->getMessage(),ENT_QUOTES,'UFT-8'),"');</script>";
}
}else{
	// 입력값이 없거나 유효하지 않은 경우
	echo"<script>alert('잘못된 요청입니다.');</script>";
}

// 리디렉션
echo"<script>location.href='notice_list2.php';</script>";

$conn=null;

?>

 

 

보안강화(delete.php)