Unrestricted File Upload

از Secure Coding

Unrestricted File Upload به معنی آپلود فایل بدون محدودیت است. در این نوع آسیب پذیری، مهاجم قادر است فایلی را بر روی سرور یا برنامه‌ی وب آپلود کند و از آن استفاده کند، بدون اینکه نرم‌افزار بررسی کند که فایل دارای محتوای مجاز است یا خیر. این نوع آسیب‌پذیری می‌تواند به دلیل ضعف در برنامه‌نویسی و عدم تایید درستی فرم‌ها و فایل‌های آپلود شده رخ دهد.

به عنوان مثال، فرض کنید یک وب سایت فایل‌هایی را به صورت آنلاین برای دانلود در اختیار کاربران قرار می‌دهد و فرمی برای آپلود فایل‌ها نیز در سایت قرار دارد. اگر برنامه‌نویسی از فیلترهای امنیتی مناسبی برای محدود کردن نوع و سایز فایل‌های آپلود شده استفاده نکند، یک هکر قادر است فایل مخربی را با نام فایل‌های معمولی آپلود کرده و در سایت بارگذاری کند. به این ترتیب، کاربرانی که فایل را دانلود کنند با فایل مخرب روبرو خواهند شد و اطلاعات شخصی و حساس آن‌ها در خطر قرار خواهد گرفت.

به همین دلیل، برای جلوگیری از این نوع حملات، باید از روش‌های امنیتی مناسبی برای آپلود فایل‌ها استفاده کرد. مثلا باید برنامه‌نویسی از فیلترهای امنیتی و دسترسی‌های کاربران به فایل‌ها برای کنترل دقیق و بررسی داده‌های آپلود شده استفاده کند. همچنین توصیه می‌شود که فایل‌های آپلود شده توسط کاربران در یک پوشه‌ی جداگانه بارگزاری گردد.


<?php
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
  $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
  if($check !== false) {
    echo "File is an image - " . $check["mime"] . ".";
    $uploadOk = 1;
  } else {
    echo "File is not an image.";
    $uploadOk = 0;
  }
}

// Check if file already exists
if (file_exists($target_file)) {
  echo "Sorry, file already exists.";
  $uploadOk = 0;
}

// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
  echo "Sorry, your file is too large.";
  $uploadOk = 0;
}

// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
  echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
  $uploadOk = 0;
}

// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
  echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
  if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
    echo "The file ". htmlspecialchars( basename( $_FILES["fileToUpload"]["name"])). " has been uploaded.";
  } else {
    echo "Sorry, there was an error uploading your file.";
  }
}
?>

روش های جلوگیری

محدود کردن نوع فایل‌های قابل بارگذاری

باید محدودیتی برای نوع فایل‌های قابل بارگذاری تعریف کنید تا کاربران نتوانند فایل‌های خطرناک (مثل فایل‌های اجرایی یا فایل‌های php) را به سرور آپلود کنند. برای این کار، می‌توانید از تابع pathinfo() استفاده کنید تا پسوند فایل را بررسی کنید. همچنین، می‌توانید با استفاده از تابع getimagesize() بررسی کنید که فایل آپلود شده تصویری است یا خیر.


روش های جلوگیری در PHP

$allowed_extensions = array('jpg', 'jpeg', 'png', 'gif');
$file_extension = pathinfo($_FILES['fileToUpload']['name'], PATHINFO_EXTENSION);
if (!in_array($file_extension, $allowed_extensions)) {
    // فایل آپلود شده دارای پسوند نامعتبر است
    die("Sorry, only JPG, JPEG, PNG & GIF files are allowed.");
}


محدود کردن اندازه فایل‌های قابل بارگذاری

باید حجم فایل‌هایی که کاربران می‌توانند آپلود کنند را محدود کنید تا از زمینه‌ای برای حمله به سرور جلوگیری شود. برای این کار، می‌توانید مقدار upload_max_filesize را در تنظیمات PHP تغییر دهید یا از تابع $_FILES['fileToUpload']['size'] برای بررسی اندازه فایل‌های آپلود شده استفاده کنید.


روش های جلوگیری در PHP

$max_file_size = 500000; // حداکثر اندازه فایل (500 کیلوبایت)
if ($_FILES['fileToUpload']['size'] > $max_file_size) {
    // فایل آپلود شده حجم بیشتری از حداکثر مجاز دارد
    die("Sorry, your file is too large.");
}


ذخیره فایل‌های آپلود شده در مسیری خاص

برای جلوگیری از دسترسی کنترل نشده به فایل‌های آپلود شده، باید فایل‌ها را در یک مسیر خاص ذخیره کنید که قابل دسترسی توسط کاربران نباشد. همچنین، نام فایل‌ها را باید به گونه‌ای تغییر دهید که توسط کاربران قابل پیش‌بینی نباشد.


روش های جلوگیری در PHP

$target_dir = "/var/www/uploads/"; // مسیر ذخیره فایل‌های آپلود شده
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
$new_filename = uniqid('', true) . '.' . $imageFileType;
$new_target_file = $target_dir . $new_filename;
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $new_target_file);


بررسی محتوای فایل‌های آپلود شده

برای جلوگیری از آسیب‌های امنیتی ناشی از بارگذاری فایل‌های خطرناک، باید محتوای فایل‌های آپلود شده را بررسی کنید. به عنوان مثال، اگر کاربران قادر به بارگذاری فایل‌های PHP باشند، ممکن است توسط فایل‌های آپلود شده کدهای خطرناک در سرور اجرا شوند.

روش های جلوگیری در PHP

$target_dir = "/var/www/uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
$new_filename = uniqid('', true) . '.' . $imageFileType;
$new_target_file = $target_dir . $new_filename;

// بررسی محتوای فایل آپلود شده برای جلوگیری از بارگذاری فایل‌های خطرناک
if ($imageFileType === 'php') {
    die("Sorry, PHP files are not allowed.");
} else if ($imageFileType === 'jpg' || $imageFileType === 'jpeg' || $imageFileType === 'png' || $imageFileType === 'gif') {
    $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
    if($check !== false) {
        move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $new_target_file);
    } else {
        die("File is not an image.");
    }
} else {
    die("Sorry, only JPG, JPEG")
}