์จ๋ผ์ธ ๊ฐ์
>PHP - ์ค๊ธ
๐ PHP ์ค๊ธ - 4์ฃผ์ฐจ: ํ์ผ ์ ๋ก๋ ๋ฐ ์ด๋ฏธ์ง ์ฒ๋ฆฌ - 03 ์ ๋ก๋๋ ํ์ผ ์ ํจ์ฑ ๊ฒ์ฌ (ํ์ฅ์, ํฌ๊ธฐ)
				์ฃผ์ ํ๋ก๊ทธ๋จ ์คํ
- ํ์ : 10.0
 - ๋ผ์ด์ ์ค: free
 - ์ด์์ฒด์ :
 - ํ์ผ ํฌ๊ธฐ: 0
 
ํผ๋๋ฐฑ ๋ฐ ๋ค์ด๋ก๋
- ์ฌ์ฉ์ ํ์ : 10.0
 - ๋ค์ด๋ก๋ ์: 1
 - ์กฐํ์: 82
 
์ ์กฐ์ฌ ๋ฐ ๋ฑ๋ก ์ ๋ณด
- ์ ์์ฌ: LUZENSOFT
 - ๋ฑ๋ก์ผ: 2025-07-26 11:48:47
 
- ์ค๋ช
๐ PHP ์ค๊ธ - 4์ฃผ์ฐจ: ํ์ผ ์ ๋ก๋ ๋ฐ ์ด๋ฏธ์ง ์ฒ๋ฆฌ - 03 ์ ๋ก๋๋ ํ์ผ ์ ํจ์ฑ ๊ฒ์ฌ (ํ์ฅ์, ํฌ๊ธฐ)
ํ์ผ #์ ๋ก๋ ๊ธฐ๋ฅ์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋งค์ฐ ํํ๊ฒ ์ฌ์ฉ๋ฉ๋๋ค. ์ฌ์ฉ์๋ก๋ถํฐ ํ์ผ์ ๋ฐ์ ์๋ฒ์ ์ ์ฅํ๋ ๊ฒ์ ํธ๋ฆฌํ์ง๋ง, ๋์์ ๋ณด์๊ณผ ์์ ์ฑ ์ธก๋ฉด์์ ์ค์ํ ๊ณ ๋ ค ์ฌํญ์ ์๊ณ ์์ต๋๋ค. ํนํ, ์ ์์ ์ธ ํ์ผ ์ ๋ก๋๋ฅผ ํตํด ์๋ฒ๊ฐ ์์๋๊ฑฐ๋ ์์ธก ๋ถ๊ฐ๋ฅํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๋ง๊ธฐ ์ํด ์ฒ ์ ํ #์ ํจ์ฑ_๊ฒ์ฌ(#validation)๊ฐ ํ์์ ์ ๋๋ค.
์ ํ์ผ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์ค์ํ๊ฐ์?
ํ์ผ ์ ๋ก๋ ์ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํ ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฌ๊ฐํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
๋ณด์ ์ทจ์ฝ์ : ์คํ ๊ฐ๋ฅํ ์คํฌ๋ฆฝํธ ํ์ผ(.php, .asp, .exe ๋ฑ)์ด ์ ๋ก๋๋์ด ์๋ฒ์์ ์คํ๋ ๊ฒฝ์ฐ, ์น์(webshell) ๊ณต๊ฒฉ ๋ฑ์ผ๋ก ์ด์ด์ ธ ์๋ฒ๊ฐ ์์ ํ ์ฅ์ ๋ ์ ์์ต๋๋ค.
์๋น์ค ๊ฑฐ๋ถ (DoS) ๊ณต๊ฒฉ: ๋งค์ฐ ํฐ ํ์ผ์ด ์ง์์ ์ผ๋ก ์ ๋ก๋๋์ด ์๋ฒ์ ๋์คํฌ ๊ณต๊ฐ์ด ๊ณ ๊ฐ๋๊ฑฐ๋, ๋คํธ์ํฌ ๋์ญํญ์ ์๋ชจ์์ผ ์ ์์ ์ธ ์๋น์ค๊ฐ ๋ถ๊ฐ๋ฅํด์ง ์ ์์ต๋๋ค.
๋ฐ์ดํฐ ์ค์ผ: ์์์น ๋ชปํ ํ์์ ํ์ผ์ด ์ ๋ก๋๋์ด ์ ํ๋ฆฌ์ผ์ด์  ๋ก์ง์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๊ฑฐ๋, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋ชป๋ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ๊ฒฝํ ์ ํ: ์๋ชป๋ ํ์ผ ํ์์ด๋ ๋๋ฌด ํฐ ํ์ผ ๋๋ฌธ์ ์ ๋ก๋์ ์คํจํ์ ๋, ์ ์ ํ ํผ๋๋ฐฑ์ด ์์ผ๋ฉด ์ฌ์ฉ์๊ฐ ํผ๋์ ๊ฒช์ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ #ํ์ผ_์ ๋ก๋ ๊ธฐ๋ฅ์ ๊ตฌํํ ๋๋ ์๋ฒ ์ธก์์ ๋ฐ๋์ #ํ์ฅ์, #ํ์ผ_ํฌ๊ธฐ, #MIME_ํ์ ๋ฑ์ ๊ผผ๊ผผํ๊ฒ ํ์ธํด์ผ ํฉ๋๋ค.
์ ๋ก๋๋ ํ์ผ ์ ๋ณด ํ์ธํ๊ธฐ
PHP์์ ํ์ผ ์
๋ก๋๊ฐ ์ด๋ฃจ์ด์ง๋ฉด, #$_FILES ์ ์ญ ๋ณ์์ ์
๋ก๋๋ ํ์ผ์ ์ ๋ณด๊ฐ ๋ฐฐ์ด ํํ๋ก ์ ์ฅ๋ฉ๋๋ค. ์ด ๋ฐฐ์ด์ ํตํด ํ์ผ์ ์ด๋ฆ, ํ์
, ํฌ๊ธฐ, ์์ ์ ์ฅ ๊ฒฝ๋ก ๋ฑ์ ํ์ธํ  ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, <input type="file" name="my_file"> ํํ๋ก ํ์ผ์ ์
๋ก๋ํ๋ค๋ฉด, $_FILES['my_file'] ๋ฐฐ์ด์๋ ๋ค์๊ณผ ๊ฐ์ ์ ๋ณด๊ฐ ๋ด๊น๋๋ค.
PHP
$_FILES['my_file'] = [
    'name' => '์๋ณธ_ํ์ผ๋ช
.jpg',    // ํด๋ผ์ด์ธํธ๊ฐ ์ ์กํ ์๋ณธ ํ์ผ ์ด๋ฆ
    'type' => 'image/jpeg',      // ํ์ผ์ MIME ํ์
 (๋ธ๋ผ์ฐ์ ๊ฐ ์ ์ก)
    'tmp_name' => '/tmp/phpXyZ123', // ์๋ฒ์ ์์๋ก ์ ์ฅ๋ ํ์ผ์ ๊ฒฝ๋ก
    'error' => 0,                // ํ์ผ ์
๋ก๋ ์ค๋ฅ ์ฝ๋ (0์ ์ค๋ฅ ์์)
    'size' => 123456             // ํ์ผ์ ํฌ๊ธฐ (๋ฐ์ดํธ ๋จ์)
];
์ฐ๋ฆฌ๋ ์ด ์ ๋ณด๋ค์ ํ์ฉํ์ฌ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์งํํ ๊ฒ์ ๋๋ค.
1. ํ์ฅ์ ์ ํจ์ฑ ๊ฒ์ฌ
#ํ์ฅ์ ๊ฒ์ฌ๋ ํ์ผ์ ์ข
๋ฅ๋ฅผ ์ ํํ์ฌ ์ ์ฌ์ ์ธ ์ํ์ ์ค์ด๋ ์ค์ํ ๋จ๊ณ์
๋๋ค. ํ์ง๋ง ๋จ์ํ ํ์ผ ์ด๋ฆ์ ํ์ฅ์๋ง ํ์ธํ๋ ๊ฒ์ ์์ ํ์ง ์์ต๋๋ค. ์
์์ ์ธ ์ฌ์ฉ์๋ ํ์ผ ์ด๋ฆ๋ง image.jpg.php์ ๊ฐ์ด ์์ผ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๋ฐ๋ผ์ #MIME_ํ์
($_FILES['my_file']['type'])๊ณผ ์ค์  ํ์ผ ๋ด์ฉ์ ๊ธฐ๋ฐ์ผ๋ก ํ ๊ฒ์ฌ๋ฅผ ๋ณํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
1-1. ํ์ฉ๋ ํ์ฅ์ ๋ฆฌ์คํธ ์ ์
์ ๋ก๋๋ฅผ ํ์ฉํ ํ์ฅ์๋ฅผ ๋ฐฐ์ด๋ก ๋ฏธ๋ฆฌ ์ ์ํฉ๋๋ค.
PHP
<?php
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];
$max_file_size = 5 * 1024 * 1024; // 5MB
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['upload_file'])) {
    $file = $_FILES['upload_file'];
    // ํ์ผ ์
๋ก๋ ์ค๋ฅ ํ์ธ
    if ($file['error'] !== UPLOAD_ERR_OK) {
        echo "ํ์ผ ์
๋ก๋ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: " . $file['error'];
        exit;
    }.
1-2. ํ์ผ ์ด๋ฆ์์ ํ์ฅ์ ์ถ์ถ ๋ฐ ๊ฒ์ฌ
pathinfo() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํ์ผ ์ด๋ฆ์์ ํ์ฅ์๋ฅผ ์ถ์ถํ๊ณ , ํ์ฉ๋ ๋ฆฌ์คํธ์ ํฌํจ๋๋์ง ํ์ธํฉ๋๋ค.
PHP
    $file_extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    if (!in_array($file_extension, $allowed_extensions)) {
        echo "ํ์ฉ๋์ง ์๋ ํ์ผ ํ์ฅ์์
๋๋ค. ํ์ฉ๋๋ ํ์ฅ์: " . implode(', ', $allowed_extensions);
        exit;
    }.
1-3. MIME ํ์ ๊ฒ์ฌ (๋ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ)
๋ธ๋ผ์ฐ์ ๊ฐ ์ ๊ณตํ๋ #MIME_ํ์
($_FILES['upload_file']['type'])์ ํ์ธํ๋ ๊ฒ์ ์ผ์ฐจ์ ์ธ ๋ณด์์ ๋์์ด ๋ฉ๋๋ค.
PHP
    // ๋ธ๋ผ์ฐ์ ๊ฐ ์ ๊ณตํ๋ MIME ํ์
 ๊ฒ์ฌ (์ผ์ฐจ์ )
    $allowed_mime_types = [
        'image/jpeg',
        'image/png',
        'image/gif',
        'application/pdf'
    ];
    if (!in_array($file['type'], $allowed_mime_types)) {
        echo "ํ์ฉ๋์ง ์๋ ํ์ผ ํ์
์
๋๋ค. ์ค์  MIME ํ์
: " . $file['type'];
        exit;
    }.
๋์ฑ ๊ฐ๋ ฅํ ๊ฒ์ฌ๋ฅผ ์ํด์๋ PHP์ finfo_open() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํ์ผ์ ์ค์  ๋ด์ฉ์ ๊ธฐ๋ฐ์ผ๋ก MIME ํ์
์ ํ์ธํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ ํ์ผ ํ์ฅ์๋ฅผ ์์ธ ๊ฒฝ์ฐ์๋ ์ค์  ํ์
์ ํ์
ํ  ์ ์๊ฒ ํด์ค๋๋ค.
PHP
    // ์ค์  ํ์ผ ๋ด์ฉ ๊ธฐ๋ฐ MIME ํ์
 ๊ฒ์ฌ (๊ฐ๋ ฅ ์ถ์ฒ)
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $real_mime_type = finfo_file($finfo, $file['tmp_name']);
    finfo_close($finfo);
    if (!in_array($real_mime_type, $allowed_mime_types)) {
        echo "ํ์ผ ๋ด์ฉ๊ณผ ์ผ์นํ์ง ์๋ ํ์
์
๋๋ค. ์ค์  ํ์
: " . $real_mime_type;
        exit;
    }.
2. ํ์ผ ํฌ๊ธฐ ์ ํจ์ฑ ๊ฒ์ฌ
#ํ์ผ_ํฌ๊ธฐ ๊ฒ์ฌ๋ ์๋ฒ์ ๋์คํฌ ๊ณต๊ฐ์ ๋ณดํธํ๊ณ  ์๋น์ค ๊ฑฐ๋ถ ๊ณต๊ฒฉ์ ๋ฐฉ์งํ๋ ๋ฐ ํ์์ ์
๋๋ค. PHP ์ค์ (php.ini)์์ upload_max_filesize์ post_max_size๋ก ์ต๋ ์
๋ก๋ ํฌ๊ธฐ๋ฅผ ์ ํํ  ์ ์์ง๋ง, ์ ํ๋ฆฌ์ผ์ด์
 ๋ ๋ฒจ์์ ๋ ์ธ๋ฐํ๊ฒ ์ ์ดํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
2-1. ์ต๋ ํ์ผ ํฌ๊ธฐ ์ ์
ํ์ฉํ ์ต๋ ํ์ผ ํฌ๊ธฐ๋ฅผ ๋ฐ์ดํธ ๋จ์๋ก ์ ์ํฉ๋๋ค.
PHP
    $max_file_size = 5 * 1024 * 1024; // 5MB๋ก ์ ํ
    if ($file['size'] > $max_file_size) {
        echo "ํ์ผ ํฌ๊ธฐ๊ฐ ๋๋ฌด ํฝ๋๋ค. ์ต๋ " . ($max_file_size / (1024 * 1024)) . "MB๊น์ง ์
๋ก๋ ๊ฐ๋ฅํฉ๋๋ค.";
        exit;
    }.
3. ์ต์ข ์ฝ๋ ์์ ๋ฐ ํ์ผ ์ด๋
๋ชจ๋  ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํต๊ณผํ ํ์ผ์ ์ํ๋ ์๋ฒ ๋๋ ํ ๋ฆฌ๋ก ์ด๋์์ผ์ผ ํฉ๋๋ค. ์ด ๋ move_uploaded_file() ํจ์๋ฅผ ์ฌ์ฉํ๋ฉฐ, ํ์ผ ์ด๋ฆ ์ถฉ๋์ ํผํ๊ธฐ ์ํด ์ ๋ํฌํ ํ์ผ ์ด๋ฆ์ ์์ฑํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค.
PHP
<?php
// ์
๋ก๋ ์ค์ 
$upload_dir = 'uploads/'; // ํ์ผ์ ์ ์ฅํ  ๋๋ ํ ๋ฆฌ (์น ์๋ฒ๊ฐ ์ฐ๊ธฐ ๊ถํ์ด ์์ด์ผ ํจ)
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];
$allowed_mime_types = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
$max_file_size = 5 * 1024 * 1024; // 5MB
// ์
๋ก๋ ๋๋ ํ ๋ฆฌ๊ฐ ์์ผ๋ฉด ์์ฑ (๊ถํ 0755 ๋๋ 0777์ ์ฃผ์)
if (!is_dir($upload_dir)) {
    mkdir($upload_dir, 0755, true);
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['upload_file'])) {
    $file = $_FILES['upload_file'];
    // 1. ํ์ผ ์
๋ก๋ ์ค๋ฅ ํ์ธ
    if ($file['error'] !== UPLOAD_ERR_OK) {
        switch ($file['error']) {
            case UPLOAD_ERR_INI_SIZE:
            case UPLOAD_ERR_FORM_SIZE:
                echo "์
๋ก๋๋ ํ์ผ์ด PHP ์ค์ ๋ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ด๊ณผํ์ต๋๋ค.";
                break;
            case UPLOAD_ERR_PARTIAL:
                echo "ํ์ผ์ด ๋ถ๋ถ์ ์ผ๋ก๋ง ์
๋ก๋๋์์ต๋๋ค.";
                break;
            case UPLOAD_ERR_NO_FILE:
                echo "์
๋ก๋๋ ํ์ผ์ด ์์ต๋๋ค.";
                break;
            case UPLOAD_ERR_NO_TMP_DIR:
                echo "์์ ๋๋ ํ ๋ฆฌ๊ฐ ์์ต๋๋ค.";
                break;
            case UPLOAD_ERR_CANT_WRITE:
                echo "๋์คํฌ์ ํ์ผ์ ์ธ ์ ์์ต๋๋ค.";
                break;
            case UPLOAD_ERR_EXTENSION:
                echo "PHP ํ์ฅ ๊ธฐ๋ฅ์ ์ํด ํ์ผ ์
๋ก๋๊ฐ ์ค์ง๋์์ต๋๋ค.";
                break;
            default:
                echo "์ ์ ์๋ ํ์ผ ์
๋ก๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.";
        }
        exit;
    }
    // 2. ํ์ผ ํฌ๊ธฐ ์ ํจ์ฑ ๊ฒ์ฌ
    if ($file['size'] > $max_file_size) {
        echo "ํ์ผ ํฌ๊ธฐ๊ฐ ๋๋ฌด ํฝ๋๋ค. ์ต๋ " . ($max_file_size / (1024 * 1024)) . "MB๊น์ง ์
๋ก๋ ๊ฐ๋ฅํฉ๋๋ค.";
        exit;
    }
    // 3. ํ์ฅ์ ๊ฒ์ฌ
    $file_extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    if (!in_array($file_extension, $allowed_extensions)) {
        echo "ํ์ฉ๋์ง ์๋ ํ์ผ ํ์ฅ์์
๋๋ค. ํ์ฉ๋๋ ํ์ฅ์: " . implode(', ', $allowed_extensions);
        exit;
    }
    // 4. MIME ํ์
 ๊ฒ์ฌ (๊ฐ์ฅ ์ค์)
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $real_mime_type = finfo_file($finfo, $file['tmp_name']);
    finfo_close($finfo);
    if (!in_array($real_mime_type, $allowed_mime_types)) {
        echo "ํ์ผ ๋ด์ฉ๊ณผ ์ผ์นํ์ง ์๋ ํ์
์
๋๋ค. ์ค์  ํ์
: " . $real_mime_type;
        exit;
    }
    // ๋ชจ๋  ์ ํจ์ฑ ๊ฒ์ฌ ํต๊ณผ ํ ํ์ผ ์ด๋
    // ํ์ผ ์ด๋ฆ ์ถฉ๋ ๋ฐฉ์ง๋ฅผ ์ํด ๊ณ ์ ํ ํ์ผ ์ด๋ฆ ์์ฑ
    $new_file_name = uniqid() . '.' . $file_extension;
    $destination_path = $upload_dir . $new_file_name;
    if (move_uploaded_file($file['tmp_name'], $destination_path)) {
        echo "ํ์ผ ์
๋ก๋ ๋ฐ ์ ํจ์ฑ ๊ฒ์ฌ ์ฑ๊ณต! ํ์ผ๋ช
: " . $new_file_name;
        // ์ด์  $destination_path์ ์ ์ฅ๋ ํ์ผ์ ๋ํ ์ถ๊ฐ ์์
์ ํ  ์ ์์ต๋๋ค (์: ์ด๋ฏธ์ง ์ฒ๋ฆฌ, DB ์ ์ฅ).
    } else {
        echo "ํ์ผ์ ์ง์ ๋ ๋๋ ํ ๋ฆฌ๋ก ์ด๋ํ๋ ๋ฐ ์คํจํ์ต๋๋ค.";
    }
} else {
    // ์ต์ด ํ์ด์ง ๋ก๋ ์ ๋๋ ์๋ชป๋ ์์ฒญ ์
    echo "
        <form action='' method='post' enctype='multipart/form-data'>
            <label for='upload_file'>ํ์ผ ์ ํ (JPG, JPEG, PNG, GIF, PDF / ์ต๋ 5MB):</label><br>
            <input type='file' name='upload_file' id='upload_file'><br><br>
            <input type='submit' value='์
๋ก๋'>
        </form>
    ";
}
?>
๊ฒฐ๋ก
#PHP ํ์ผ #์
๋ก๋ ์ #์ ํจ์ฑ_๊ฒ์ฌ๋ ์น ์ ํ๋ฆฌ์ผ์ด์
์ #๋ณด์๊ณผ #์์ ์ฑ์ ์งํค๋ ํต์ฌ ์์์
๋๋ค. ๋จ์ํ ํด๋ผ์ด์ธํธ ์ธก ๊ฒ์ฌ์ ์์กดํ์ง ์๊ณ , ํญ์ #์๋ฒ_์ธก์์ #ํ์ฅ์, #ํ์ผ_ํฌ๊ธฐ, #MIME_ํ์
 ๋ฑ์ ๊ผผ๊ผผํ๊ฒ ๊ฒ์ฆํ๋ ์ต๊ด์ ๋ค์ฌ์ผ ํฉ๋๋ค. ํนํ finfo_open()์ ์ฌ์ฉํ #์ค์ _MIME_ํ์
 ๊ฒ์ฌ๋ ํ์ผ #ํ์ฅ์_์๋ณ์กฐ ๊ณต๊ฒฉ์ ๋ง๋ ๋ฐ ๋งค์ฐ ํจ๊ณผ์ ์
๋๋ค. ์ด๋ฌํ ๋ฐฉ์ด์ ์ธ ํ๋ก๊ทธ๋๋ฐ ์ต๊ด์ ํตํด ๋ ๊ฒฌ๊ณ ํ๊ณ  ์์ ํ ์น ์๋น์ค๋ฅผ ๊ตฌ์ถํ  ์ ์์ต๋๋ค.
๋น ๋ฅธ์๋, ๊ฐํธํ์ฌ์ฉ, ์ฅ์ ์๋VPN, ์ฌ์ฉ์ด๋ ฅ์๋ ๊นจ๋ํ ์์ดํผ
https://xn--299ao67b9qbmsf04c.net/