PHP/포스팅

[PHP] 데이터 검증

짜집퍼박사(짜박) 2024. 12. 28. 00:27

PHP 데이터 검증은 입력된 데이터를 안전하고 정확하게 처리하기 위해 필수적인 작업입니다. 데이터 검증은 보안 문제(예: XSS, SQL Injection)를 예방하고, 데이터 무결성을 유지하며, 사용자의 입력 오류를 최소화하는 데 중요한 역할을 합니다.

 

1. 데이터 검증이란?

1.1 정의

데이터 검증은 사용자 입력 데이터를 확인하고, 예상한 형식이나 범위를 벗어난 데이터는 거부하거나 처리하지 않는 과정을 말합니다.

 

1.2 검증의 목적

(1) 보안 강화: 악성 데이터로부터 시스템 보호.

(2) 정확성 보장: 유효한 데이터만 처리.

(3) 에러 방지: 데이터 무결성을 유지.

 

1.3 검증 위치

(1) 클라이언트 측 검증: 사용자가 입력한 데이터를 브라우저에서 검증(JavaScript 사용).

- 빠른 피드백 제공.

- 하지만 완전한 신뢰는 불가능(우회 가능).

(2) 서버 측 검증: PHP에서 입력 데이터를 재검증

- 필수 과정으로 모든 입력 데이터는 신뢰할 수 없음.

 

2. 데이터 검증의 종류

(1) 형식 검증

- 자열, 숫자, 이메일, URL 등 데이터 유형 확인.

(2) 범위 검증

- 숫자 범위, 날짜 범위, 문자열 길이 등 확인.

(3) 화이트리스트 검증

- 허용된 값만 수용.

(4) 필수 값 확인

- 비어 있는 값인지 확인.

(5) 커스텀 검증

- 특정 규칙(예: 패턴 매칭)에 따른 검증.

 

3. 실무에서의 데이터 검증 코드

3.1 입력 폼

index.php

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>PHP 데이터 검증 예제</title>
</head>
<body>
    <h1>데이터 입력</h1>
    <form action="process.php" method="POST">
        <label for="name">이름:</label>
        <input type="text" id="name" name="name" required>
        <br><br>

        <label for="email">이메일:</label>
        <input type="email" id="email" name="email" required>
        <br><br>

        <label for="age">나이:</label>
        <input type="number" id="age" name="age" required>
        <br><br>

        <label for="website">웹사이트:</label>
        <input type="url" id="website" name="website">
        <br><br>

        <button type="submit">제출</button>
    </form>
</body>
</html>

 

3.2 데이터 검증

process.php

<?php
require 'validators.php';

// 입력 데이터 수신
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';
$age = $_POST['age'] ?? '';
$website = $_POST['website'] ?? '';

// 데이터 검증
$errors = [];

if (!validateRequired($name)) {
    $errors[] = "이름은 필수 항목입니다.";
} elseif (!validateStringLength($name, 2, 50)) {
    $errors[] = "이름은 2자 이상, 50자 이하이어야 합니다.";
}

if (!validateRequired($email) || !validateEmail($email)) {
    $errors[] = "유효한 이메일 주소를 입력하세요.";
}

if (!validateRequired($age) || !validateNumberRange($age, 1, 120)) {
    $errors[] = "나이는 1부터 120 사이의 숫자여야 합니다.";
}

if ($website && !validateUrl($website)) {
    $errors[] = "유효한 웹사이트 URL을 입력하세요.";
}

// 결과 출력
if (empty($errors)) {
    echo "<h1>검증 성공</h1>";
    echo "이름: " . htmlspecialchars($name) . "<br>";
    echo "이메일: " . htmlspecialchars($email) . "<br>";
    echo "나이: " . htmlspecialchars($age) . "<br>";
    echo "웹사이트: " . htmlspecialchars($website) . "<br>";
} else {
    echo "<h1>검증 실패</h1>";
    echo "<ul>";
    foreach ($errors as $error) {
        echo "<li>" . htmlspecialchars($error) . "</li>";
    }
    echo "</ul>";
    echo "<a href='index.php'>돌아가기</a>";
}
?>

 

3.3 유효성 검사 함수

validators.php

<?php

/**
 * 필수 값 검증
 * @param string $value 입력 값
 * @return bool
 */
function validateRequired(string $value): bool {
    return trim($value) !== '';
}

/**
 * 문자열 길이 검증
 * @param string $value 입력 값
 * @param int $min 최소 길이
 * @param int $max 최대 길이
 * @return bool
 */
function validateStringLength(string $value, int $min, int $max): bool {
    $length = mb_strlen($value);
    return $length >= $min && $length <= $max;
}

/**
 * 이메일 형식 검증
 * @param string $email 이메일 주소
 * @return bool
 */
function validateEmail(string $email): bool {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

/**
 * 숫자 범위 검증
 * @param string|int|float $number 숫자 값
 * @param int $min 최소값
 * @param int $max 최대값
 * @return bool
 */
function validateNumberRange($number, int $min, int $max): bool {
    return filter_var($number, FILTER_VALIDATE_INT, [
        'options' => [
            'min_range' => $min,
            'max_range' => $max
        ]
    ]) !== false;
}

/**
 * URL 형식 검증
 * @param string $url URL 값
 * @return bool
 */
function validateUrl(string $url): bool {
    return filter_var($url, FILTER_VALIDATE_URL) !== false;
}

 

4. 실행 결과

입력 예

- 이름: 홍길동

- 이메일: hong@example.com

- 나이: 25

- 웹사이트: http://example.com

 

출력 결과

<h1>검증 성공</h1>
이름: 홍길동
이메일: hong@example.com
나이: 25
웹사이트: http://example.com

 

5. 보안 및 실무 체크리스트

(1) 입력 필터링: 사용자 입력 데이터는 항상 검증.

(2) 출력 이스케이프: HTML 컨텍스트에서는 htmlspecialchars() 사용.

(3) 에러 핸들링: 상세한 에러 메시지는 사용자에게 노출하지 않음.

(4) 데이터베이스 검증: 추가로 SQL Injection을 방지하기 위해 준비된 문장(Prepared Statements) 사용.

 

With ChatGPT

'PHP > 포스팅' 카테고리의 다른 글

[PHP] 중요 데이터 금지  (0) 2024.12.27
[PHP] URL 길이 제한  (0) 2024.12.27
[PHP] CSRF 공격 방지 데이터 베이스 활용  (0) 2024.12.26
[PHP] CSRF 공격 방지  (0) 2024.12.26
[PHP] XSS 방지  (0) 2024.12.26