일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- php 파일 업로드하기
- 파일 업로드 취약점
- THM
- Cookie
- Leviathan
- active reconnaissance
- BANDiT
- Server Side Request Forgery
- active recon
- php 로그인 페이지 만들기
- php file upload
- OS Command Injection
- Cryptography
- War Game
- php login page
- Authentication
- file upload
- Recon
- over the wire
- ssrf
- overthewire
- SQLi
- privilege escalation
- access control
- php To Do List
- FTZ
- php
- tryhackme
- sql injection
- Reconnaissance
- Today
- Total
R's Hacking Daily Log
php - Mini Project 1 - (5) 본문
[ Mini Project - Last ]
index.php에 접속하면 로그인할 수 있는 form과 회원가입할 수 있는 register 버튼이 제공된다.
계정 정보를 입력하고 LOGIN 버튼을 클릭하면 login_check.php가 실행되고
REGISTER 버튼을 클릭하면 register.php가 실행된다는 건 이미 알고 있는 사실!
register.php에서 사용자 정보를 입력한 후 버튼을 클릭하면 form tag에 지정된 경로,
즉 register_update.php로 이동하게 된다.
이 말은 즉슨 다음으로 살펴볼 내용이 register_update.php라는 말씀!
전체적인 흐름을 보면 register_update.php에서 어떤 기능이 실행되는지 예상할 수 있을 것이다.
[ register_update.php ]
<?php
include("./dbconn.php");
$mode = $_POST['mode'];
switch($mode) {
case 'insert':
$mb_id = trim($_POST['mb_id']);
$title = "Register";
break;
case 'modify':
$mb_id = trim($_SESSION['ss_mb_id']);
$title = 'EDIT info';
break;
default:
echo "<script>alert('Can't get mode value');</script>";
echo "<script>location.replace('./register.php');</script>";
break;
}
if(!$_POST['mb_id']) {
echo "<script>alert('Can't get ID');</script>";
echo "<script>location.replace('./register.php')</script>";
exit();
}
if(!$_POST['mb_password']) {
echo "<script>alert('Can't get Password');</script>";
echo "<script>location.replace('./register.php')</script>";
exit();
}
if($_POST['mb_password'] != $_POST['mb_password_re']) {
echo "<script>alert('Password doesn't match');</script>";
echo "<script>location.replace('./register.php')</script>";
exit();
}
if(!$_POST['mb_name']) {
echo "<script>alert('Can't get Name');</script>";
echo "<script>location.replace('./register.php')</script>";
exit();
}
if(!$_POST['mb_email']) {
echo "<script>alert('Can't get email');</script>";
echo "<script>location.replace('./register.php')</script>";
exit();
}
$mb_password = trim($_POST['mb_password']);
$mb_password_re = trim($_POST['mb_password_re']);
$mb_name = trim($_POST['mb_name']);
$mb_email = trim($_POST['mb_email']);
$mb_job = trim($_POST['mb_job']) ?? '';
$mb_gender = trim($_POST['mb_gender']) ?? '';
$mb_language = isset($_POST['mb_language']) ? implode(",", $_POST['mb_language']) : "";
$mb_datetime = date('Y-m-d H:i:s', time());
$sql = "SELECT PASSWORD('$mb_password') AS pass";
$result = mysqli_query($conn, $sql);
$row = mysqli_fetch_assoc($result);
$mb_password = $row['pass'];
if($mode == "insert") {
$sql = "SELECT * FROM member WHERE mb_id = '$mb_id'";
$result = mysqli_query($conn, $sql);
if(mysqli_num_rows($result) > 0) {
echo "<script>alert('already using ID')</script>";
echo "<script>location.replace('./register.php');</script>";
exit();
}
$sql = "INSERT INTO member SET mb_id = '$mb_id', mb_password = '$mb_password', mb_name = '$mb_name', mb_email = '$mb_email', mb_job = '$mb_job',
mb_gender='$mb_gender', mb_language='$mb_language', mb_datetime = '$mb_datetime'";
$result = mysqli_query($conn, $sql);
} else if ($mode == 'modify') {
$sql = "UPDATE member SET mb_password = '$mb_password', mb_email = '$mb_email', mb_job = '$mb_job',
mb_gender='$mb_gender', mb_language='$mb_language' WHERE mb_id = '$mb_id' ";
$result = mysqli_query($conn, $sql);
}
if ($result) {
echo "<script>alert('completed ".$title."')</script>";
echo "<script>location.replace('./member_list.php')</script>";
exit();
} else {
echo "fail to make : ".mysqli_error($conn);
mysqli_close($conn);
}
register_update.php code는 모두 php와 관련된 내용으로 지금까지 살펴본 코드 중에서
php 코드가 제일 긴 코드이다.
register.php까지의 흐름을 생각해봤을 때 register_update.php에서는
(1) 사용자가 회원가입을 하기 위해 입력한 정보 또는
(2) 사용자가 수정한 정보
를 DB에다 적용하는 과정이 실행되어야 한다.
register.php에서는 단순히 사용자의 정보를 입력받아 action 경로로 데이터를 전달만 하기 때문에
데이터의 중복 여부, 공백 여부 등의 검사 과정도 필요하다.
[ 코드 설명 ]
그렇다면 코드가 어떻게 작성되었는 지 바로 알아보자!
<?php
include("./dbconn.php");
$mode = $_POST['mode'];
register_update.php는 데이터 베이스에 정보를 UPDATE or INSERT해야하기 때문에
dbconn.php로 DB에 연결을 해준다.
register_update.php가 실행되는 경로를 생각해 보면
(1) index.php에서 REGISTER 버튼을 클릭한 후 회원 가입
(2) member_list.php에서 EDIT 버튼을 클릭해서 회원 정보를 수정
과 같이 두 가지 경우가 존재한다.
register.php에서는
(1)의 경우, if문에서 $mode를 modify로 설정
(2)의 경우, else문에서 $mode를 insert로 설정했다.
따라서 $mode 값에 따라 상황에 맞는 처리를 해야하기 때문에
hidden type으로 전달한 $mode 값을 $_POST에서 가져오는 것이다.
switch($mode) {
case 'insert':
$mb_id = trim($_POST['mb_id']);
$title = "Register";
break;
case 'modify':
$mb_id = trim($_SESSION['ss_mb_id']);
$title = 'EDIT info';
break;
default:
echo "<script>alert('Can't get mode value');</script>";
echo "<script>location.replace('./register.php');</script>";
break;
}
그렇게 할당한 $mode 값을 기준으로 $mb_id & $title을 달리 설정해 준다.
case 'insert' )
INSERT는 새로운 row를 데이터베이스에 삽입할 때 사용하는 sql문으로
회원 계정이 없는 새로운 정보를 추가한다는 의미로 해석할 수 있다.
login_check.php에서 계정 정보가 유효하면 session을 만들도록 구현해놨는 데
계정이 없는 경우는 session이 없기 때문에 $mb_id를 register.php에서 ID input에 입력한 값으로 할당하는 것이다.
case 'modify' )
insert 경우와 달리 modify는 값을 수정한다는 의미이기 때문에 기존에 등록한 정보를 고치는 거라 할 수 있다.
이는 계정이 이미 존재한다는 뜻이기 때문에 로그인이 가능하고 그 말은 결국, session을 생성한다는 것이다.
그렇기 때문에 $_POST가 아닌 $_SESSION으로부터 $mb_id 값을 할당받는 다는 게
경우에 따른 차이점이라 할 수 있다.
$mode 값이 'modify' or 'insert'가 아닌 경우는 default문으로 처리해 준다.
if(!$_POST['mb_id']) {
echo "<script>alert('Can't get ID');</script>";
echo "<script>location.replace('./register.php')</script>";
exit();
}
if(!$_POST['mb_password']) {
echo "<script>alert('Can't get Password');</script>";
echo "<script>location.replace('./register.php')</script>";
exit();
}
if($_POST['mb_password'] != $_POST['mb_password_re']) {
echo "<script>alert('Password doesn't match');</script>";
echo "<script>location.replace('./register.php')</script>";
exit();
}
if(!$_POST['mb_name']) {
echo "<script>alert('Can't get Name');</script>";
echo "<script>location.replace('./register.php')</script>";
exit();
}
if(!$_POST['mb_email']) {
echo "<script>alert('Can't get email');</script>";
echo "<script>location.replace('./register.php')</script>";
exit();
}
그 후에는 input으로 전달된 값을 검사하는 과정을 거친다.
우선 id & password & password_re & name & email 값이 공백인지 아닌지를 if문으로 확인한다.
그 말은 즉슨 이 5가지는 반드시 작성되어야 하는 내용이라는 의미!
비밀번호의 경우에는 확인차 입력한 password_re와 password가 일치하는 지의 여부도 확인한다.
공백인 데이터가 있다면 해당 값이 없다는 문구를 출력한 후, register.php로 이동!
$mb_password = trim($_POST['mb_password']);
$mb_password_re = trim($_POST['mb_password_re']);
$mb_name = trim($_POST['mb_name']);
$mb_email = trim($_POST['mb_email']);
$mb_job = trim($_POST['mb_job']) ?? '';
$mb_gender = trim($_POST['mb_gender']) ?? '';
$mb_language = isset($_POST['mb_language']) ? implode(",", $_POST['mb_language']) : "";
$mb_datetime = date('Y-m-d H:i:s', time());
반드시 제출되어야하는 값이 모두 공백이 아니라면 $_POST로부터 각 변수에 사용자의 입력값을 할당한다.
job & gender & language의 경우,
사용자로부터 반드시 전달받는 값이 아니기 때문에 값이 NULL이라면 공백 처리해 버린다.
ex ) $_POST['mb_job'] ?? ' ' : mb_job 값이 없다면, 공백 처리해!
if($mode == "insert") {
$sql = "SELECT * FROM member WHERE mb_id = '$mb_id'";
$result = mysqli_query($conn, $sql);
if(mysqli_num_rows($result) > 0) {
echo "<script>alert('already using ID')</script>";
echo "<script>location.replace('./register.php');</script>";
exit();
}
$sql = "INSERT INTO member SET mb_id = '$mb_id', mb_password = '$mb_password', mb_name = '$mb_name', mb_email = '$mb_email', mb_job = '$mb_job',
mb_gender='$mb_gender', mb_language='$mb_language', mb_datetime = '$mb_datetime'";
$result = mysqli_query($conn, $sql);
}
필요한 사용자 정보를 모두 준비했으니 이젠 데이터베이스에 넣어줄 차례다.
mode가 insert인 경우에는 우선 id의 사용 가능 여부를 확인한다.
sql문 결과가 1줄 이상이라는 건 회원가입 시 입력한 id가 이미 사용 중이라는 의미로
더 이상의 회원가입 절차를 진행하지 않고 register.php로 돌아가게 된다.
중복되는 id가 없다면 mb_id부터 mb_datatime까지 INSERT문으로 데이터베이스에 사용자 정보를 추가한다.
} else if ($mode == 'modify') {
$sql = "UPDATE member SET mb_password = '$mb_password', mb_email = '$mb_email', mb_job = '$mb_job',
mb_gender='$mb_gender', mb_language='$mb_language' WHERE mb_id = '$mb_id' ";
$result = mysqli_query($conn, $sql);
}
mode가 modify인 경우에는 id를 제외한 다른 값을 UPDATE문으로 변경해 준다.
이때 사용자의 id는 고유한 값으로 회원가입 후에도 변경이 불가능하다는 점을 활용해
mb_id로 정보를 수정할 사용자 row를 찾아(where mb_id = '$mb_id') 해당 row 값을 변경한다.
if ($result) {
echo "<script>alert('completed ".$title."')</script>";
echo "<script>location.replace('./member_list.php')</script>";
exit();
} else {
echo "fail to make : ".mysqli_error($conn);
mysqli_close($conn);
}
INSERT or UPDATE문의 결과를 확인해 error가 발생한 경우에는 에러 내용을 출력하고 DB 연결을 종료한다.
문제없이 sql문이 실행되었다면 member_list.php로 이동하게 되는 데,
아직 memberlist.php 내용을 살펴보진 않았지만 member_list.php에서는 session 값의 여부로
로그인하지 않는 사용자의 접근은 차단한다.
로그인 후 member_list.php에서 정보 수정 버튼을 클릭한 경우에는 문제가 없지만
회원가입을 이제 막 완료하고 member_list.php로 이동하는 경우에는 로그인 후 접속하라는 팝업 창이 뜰 것이다!
이런 경우에는 index.php에서 로그인해 주면 그만이니 당황하지 않아도 된다 :)
이번 글에서는 register.php에서 입력한 데이터가 어떻게 처리되는지에 대한 코드를 살펴보았다.
그 말은 즉슨, index.php에서 register 버튼을 눌렀을 때 필요한 코드를 모두 살펴보았다는 뜻이다!
이제는 새로운 계정을 추가해 보고 LOGIN을 시도했을 때 접근할 수 있는 member_list.php를 구현할 차례이다.
[ Next ]
(1) dbconn.php - 완료!
(2) login_check.php - 완료!
(3) register.php - 완료!
(4) member_list.php
(5) register_update.php - 완료!
'PHP' 카테고리의 다른 글
php - Mini Project 1 - (7) (0) | 2023.08.02 |
---|---|
php - Mini Project 1 - (6) (0) | 2023.08.02 |
php - Mini Project 1 - (4) (0) | 2023.08.01 |
php - Mini Project 1 - (3) (0) | 2023.07.31 |
php - Mini Project 1 - (2) (1) | 2023.07.31 |