Thread Starter
#0
Veb tətbiqlərində fayl yükləmə funksiyası tez-tez istifadə olunur, lakin düzgün idarə edilmədikdə ciddi təhlükəsizlik boşluqlarına yol aça bilər. Hakerlər bu boşluqlardan istifadə edərək zərərli skriptləri serverə yükləyə, tətbiqin idarəsini ələ keçirə və ya digər hücumlar həyata keçirə bilərlər. Buna görə də, fayl yükləmə mexanizmlərini dizayn edərkən maksimum diqqətli olmaq vacibdir.Bu mövzu süni intellekt tərəfindən yaradılıb ❗
Problemin Diaqnozu:
Ən böyük problem, yüklənən fayllara etibar etmək və onların məzmununu, tipini və ya adını lazımi qədər yoxlamadan serverdə saxlamaqdır. Bu, fayl yükləmə zəifliklərinin (məsələn, zərərli fayl yükləmə, MIME tipli aldatma) əsas səbəbidir.
Həll:
Təhlükəsiz fayl yükləmə üçün aşağıdakı addımlar atılmalıdır:
- Fayl Ölçüsünün Yoxlanılması: Yüklənəcək faylın ölçüsünü server tərəfində məhdudlaşdırın. Bu, həm resurs tükənməsinin qarşısını alır, həm də bəzi DoS hücumlarını əngəlləyir.
- Fayl Tipinin Yoxlanılması (MIME Type və Uzantı): Faylın həm MIME tipini (server tərəfində
$_FILES['file']['type']vasitəsilə), həm də uzantısını yoxlayın. Yalnız icazə verilən tiplərə (məsələn,image/jpeg,image/png) icazə verin. Qeyd: MIME tipi asanlıqla saxtalaşdırıla bilər, buna görə uzantı yoxlaması da vacibdir.
- Fayl Adının Təmizlənməsi və Yenidən Adlandırılması: İstifadəçinin təqdim etdiyi fayl adını birbaşa istifadə etməyin. Fayl adlarını unikal şəkildə (məsələn,
uniqid()və yahash()funksiyaları ilə) yenidən adlandırın və yalnız icazə verilən simvolları saxlayın. Bu, yol keçidi (path traversal) hücumlarının qarşısını alır.
- Faylın Təhlükəsiz Qovluğa Köçürülməsi: Yüklənən faylları veb-serverin birbaşa icra edə bilməyəcəyi bir qovluqda saxlayın. Əgər fayllar publik olmalıdırsa, həmin qovluqda
.htaccessvasitəsilə PHP skriptlərinin icrasını qadağan edin (məsələn,php_flag engine off).
- Antivirus Skaneri (Əlavə Təhlükəsizlik): Əgər mümkünsə, yüklənən faylları server tərəfində bir antivirus proqramı ilə skan edin.
Aşağıda PHP 8.2+ üçün nümunəvi təhlükəsiz fayl yükləmə kodu verilmişdir:
CODE
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
<?php
// Yükləmə parametrləri
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5 MB
const UPLOAD_DIR = __DIR__ . '/uploads/'; // Faylların saxlanacağı qovluq
const ALLOWED_MIME_TYPES = [
'image/jpeg',
'image/png',
'image/gif',
'application/pdf'
];
const ALLOWED_EXTENSIONS = [
'jpg',
'jpeg',
'png',
'gif',
'pdf'
];
// Yükləmə qovluğunun mövcudluğunu yoxla və yarat
if (!is_dir(UPLOAD_DIR)) {
mkdir(UPLOAD_DIR, 0755, true);
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
$file = $_FILES['file'];
// 1. Yükləmə zamanı xətanın olub-olmadığını yoxla
if ($file['error'] !== UPLOAD_ERR_OK) {
echo "[B]Xəta:[/B] Fayl yüklənərkən problem yarandı. Kod: " . $file['error'];
exit;
}
// 2. Fayl ölçüsünü yoxla
if ($file['size'] > MAX_FILE_SIZE) {
echo "[B]Xəta:[/B] Fayl ölçüsü icazə verilən həddi aşır (" . MAX_FILE_SIZE / (1024 * 1024) . " MB).";
exit;
}
// 3. Fayl tipini və uzantısını yoxla
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime_type = $finfo->file($file['tmp_name']);
if (!in_array($mime_type, ALLOWED_MIME_TYPES)) {
echo "[B]Xəta:[/B] Fayl tipi icazə verilmir: " . $mime_type;
exit;
}
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!in_array($extension, ALLOWED_EXTENSIONS)) {
echo "[B]Xəta:[/B] Fayl uzantısı icazə verilmir: " . $extension;
exit;
}
// 4. Fayl adını təmizlə və unikal ad yarat
$sanitized_filename = preg_replace('/[^a-zA-Z0-9_\-.]/', '', $file['name']); // Yalnız təhlükəsiz simvolları saxla
$new_filename = uniqid('upload_', true) . '.' . $extension;
$destination = UPLOAD_DIR . $new_filename;
// 5. Faylı təhlükəsiz yerə köçür
if (move_uploaded_file($file['tmp_name'], $destination)) {
echo "[B]Uğurlu:[/B] Fayl uğurla yükləndi: " . htmlspecialchars($new_filename);
} else {
echo "[B]Xəta:[/B] Fayl serverə köçürülə bilmədi.";
}
} else {
// Formu göstər
?>
<form action="" method="post" enctype="multipart/form-data">
<label for="file">Yükləmək üçün fayl seçin:</label>
<input type="file" name="file" id="file">
<button type="submit">Yüklə</button>
</form>
<?php
}
?>
Məntiqi Əsaslandırma:
Bu yanaşma, fayl yükləmə prosesindəki bütün potensial zəiflikləri minimuma endirir. Fayl ölçüsünün, tipinin və uzantısının həm server tərəfində yoxlanılması, həm də fayl adının unikal və təhlükəsiz şəkildə yaradılması sayəsində zərərli faylların icra olunmasının və ya serverə nəzarətin ələ keçirilməsinin qarşısı alınır.
finfo funksiyasından istifadə edərək faylın əsl MIME tipini yoxlamaq, yalnız uzantıya etibar etməkdən daha etibarlıdır, çünki uzantılar asanlıqla dəyişdirilə bilər. Faylların veb-server tərəfindən birbaşa icra oluna bilməyəcək bir qovluqda saxlanılması isə əlavə təhlükəsizlik qatı yaradır. Bu metodologiya müasir və təhlükəsiz veb tətbiqlərinin əsasını təşkil edir.