WEB - PHP, JQuery, Bootstrap

PHP 프로그래밍 시 주의해야 하는 보안 코드

초심으로 2024. 7. 3. 14:30

728x90

 

 

PHP로 웹사이트를 개발할 때 보안을 고려하는 것은 매우 중요합니다. 웹 애플리케이션의 취약점을 방지하기 위해 여러 보안 기법을 사용해야 하며, 대표적인 보안 위협과 이에 대한 방어 코드 예시를 통해 이를 설명하겠습니다.

1. SQL 인젝션 (SQL Injection)

문제점: SQL 인젝션은 사용자가 입력한 데이터를 통해 악의적인 SQL 쿼리를 실행하는 공격입니다.

예시 코드: 악의적인 사용자가 다음과 같은 입력을 통해 데이터베이스를 공격할 수 있습니다:

' OR '1'='1

해결책: SQL 쿼리를 실행하기 전에 사용자 입력을 안전하게 처리해야 합니다. 이를 위해 준비된 문(Prepared Statement)을 사용합니다.

<?php
$mysqli = new mysqli("localhost", "user", "password", "database");

// 준비된 문 생성
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);

// 변수에 사용자 입력을 대입
$username = $_POST['username'];
$password = $_POST['password'];

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

if ($result->num_rows > 0) {
    echo "Login successful!";
} else {
    echo "Invalid username or password.";
}
$stmt->close();
$mysqli->close();
?>

2. XSS (Cross-Site Scripting)

문제점: XSS는 공격자가 악의적인 스크립트를 웹 페이지에 삽입하여 다른 사용자에게 전달하는 공격입니다.

예시 코드: 사용자 입력을 직접 출력하면 XSS 공격에 노출될 수 있습니다.

<?php echo $_POST['comment']; ?>

해결책: 사용자 입력을 출력할 때 HTML 특수 문자를 이스케이프 처리합니다.

<?php
function escapeHtml($string) {
    return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
}

echo escapeHtml($_POST['comment']);
?>

3. CSRF (Cross-Site Request Forgery)

문제점: CSRF는 사용자가 인증된 상태에서 공격자가 요청을 위조하여 서버에 보내는 공격입니다.

해결책: 폼을 제출할 때 CSRF 토큰을 사용하여 요청의 유효성을 검증합니다.

<?php
// 세션 시작
session_start();

// CSRF 토큰 생성
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// 폼에 CSRF 토큰 추가
?>
<form method="post" action="submit.php">
    <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
    <input type="text" name="comment">
    <input type="submit" value="Submit">
</form>

<?php
// 폼 제출 처리
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        // 요청이 유효합니다.
        echo "Form submitted successfully.";
    } else {
        // 요청이 유효하지 않습니다.
        echo "CSRF validation failed.";
    }
}
?>

4. 세션 하이재킹(Session Hijacking)

문제점: 세션 하이재킹은 공격자가 사용자의 세션 ID를 탈취하여 사용자로 가장하는 공격입니다.

해결책: 세션 ID를 자주 재생성하고, 보안 설정을 강화합니다.

<?php
// 세션 시작
session_start();

// 세션 ID 재생성
session_regenerate_id(true);

// 세션에 보안 플래그 설정
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
ini_set('session.use_only_cookies', 1);

// 세션 데이터 설정
$_SESSION['user_id'] = $user_id;
?>

5. 파일 업로드 보안

문제점: 파일 업로드 기능은 악의적인 파일 업로드를 통해 서버를 공격할 수 있습니다.

해결책: 업로드된 파일의 MIME 타입과 확장자를 검증하고, 업로드된 파일의 저장 위치를 안전하게 관리합니다.

<?php
$allowed_extensions = ['jpg', 'png', 'gif'];
$upload_directory = 'uploads/';

if (isset($_FILES['file'])) {
    $file = $_FILES['file'];
    $file_extension = pathinfo($file['name'], PATHINFO_EXTENSION);

    // 확장자 검증
    if (in_array($file_extension, $allowed_extensions)) {
        $file_path = $upload_directory . basename($file['name']);

        // 파일 저장
        if (move_uploaded_file($file['tmp_name'], $file_path)) {
            echo "File uploaded successfully.";
        } else {
            echo "File upload failed.";
        }
    } else {
        echo "Invalid file extension.";
    }
} else {
    echo "No file uploaded.";
}
?>

6. 디렉토리 인덱싱 방지

문제점: 디렉토리 인덱싱이 활성화되어 있으면, 서버에서 특정 디렉토리의 파일 목록을 열람할 수 있습니다.

해결책: .htaccess 파일을 통해 디렉토리 인덱싱을 비활성화합니다.

Options -Indexes

7. 정적 파일 접근 제어

문제점: 서버 설정이 부적절하면 민감한 파일에 접근할 수 있습니다.

해결책: .htaccess 파일을 사용하여 특정 파일 형식에 대한 접근을 차단합니다.

<FilesMatch "\.(env|ini|log)$">
    Order allow,deny
    Deny from all
</FilesMatch>
반응형

8. 비밀번호 해싱(Password Hashing)

문제점: 비밀번호를 평문으로 저장하면 데이터베이스가 노출될 경우 심각한 문제가 발생합니다.

해결책: 비밀번호를 해시 알고리즘을 사용하여 안전하게 저장합니다.

<?php
$password = 'user_password';
$hashed_password = password_hash($password, PASSWORD_BCRYPT);

// 비밀번호 검증
if (password_verify($password, $hashed_password)) {
    echo "Password is valid!";
} else {
    echo "Invalid password.";
}
?>

9. 입력 데이터 검증(Input Validation)

문제점: 사용자가 입력한 데이터가 신뢰할 수 없으면 다양한 공격에 취약할 수 있습니다.

해결책: 입력 데이터를 철저하게 검증하고, 필요한 경우 데이터 형식을 강제 변환합니다.

<?php
function validate_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}

$username = validate_input($_POST['username']);
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
?>

10. HTTPS 사용

문제점: HTTP로 전송된 데이터는 네트워크 상에서 쉽게 가로채질 수 있습니다.

해결책: HTTPS를 사용하여 데이터를 암호화합니다. 이를 위해 서버에 SSL/TLS 인증서를 설치하고, .htaccess를 통해 HTTP 요청을 HTTPS로 리디렉션합니다.

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

위의 코드 예시들은 PHP 웹 애플리케이션 개발 시 주의해야 할 보안 사항들을 포괄적으로 다루고 있습니다. 이러한 보안 기법을 적용하여 안전하고 신뢰할 수 있는 웹 애플리케이션을 개발할 수 있습니다.

반응형