PHP
Secure file upload
Güvenli dosya yükleme için MIME denetimi, rastgele ad ve depolama ayırmayı öğrenirsin.
Güvenli dosya yükleme ilkeleri
Dosya yüklemesinde üç temel ilke: MIME denetimi, rastgele ad, depolama ayırma. finfo sınıfı (FILEINFO_MIME_TYPE) dosyanın gerçek içeriğinden MIME türünü okur; $_FILES['x']['type'] güvenilmemesi gereken tarayıcı bildirimidir. Yüklenen dosyaya bin2hex(random_bytes(16)) ile rastgele ad verilir; orijinal ad korunmaz.
Dosya web kökü dışında tutulur, indirme bir betik aracılığıyla yapılır. Uzantı allowlist ile sınırlanır (png, jpg, pdf); in_array sıkı modda (üçüncü parametre true) çağrılır. move_uploaded_file geçici dosyayı hedefe taşır.
Rastgele dosya adı ve depolama
Orijinal dosya adı kullanıcı tarafından kontrol edilir; yol gezisi saldırısı (../../etc/passwd) içerebilir. Bu yüzden bin2hex(random_bytes(16)) ile 32 karakterli rastgele ad üretir, allowlist'ten gelen uzantıyı eklersin. Dosya /var/www/uploads gibi web kökü dışında saklanır; indirme bir denetleyici betik aracılığıyla yapılır.
Allowlist ['png', 'jpg', 'pdf'] biçiminde tutulur; in_array($ext, $allowed, true) ile sıkı denetim yapılır. move_uploaded_file geçici dosyayı hedefe taşır ve yol gezisini engeller. Çıktı olarak yalnızca adın uzunluğunu ya da durum kodunu yazdırmalısın; rastgele adın kendisini yazdırma.
Uygulama generateUploadName fonksiyonu yaz
generateUploadName(string $ext, array $allowed): string fonksiyonu tanımla. in_array($ext, $allowed, true) false ise boş dize döndür. true ise bin2hex(random_bytes(8)) . "." . $ext döndür. $allowed = ["png", "jpg", "pdf"] tanımla. generateUploadName("png", $allowed) ve generateUploadName("exe", $allowed) çağır; ilkinin uzunluğu 20 mi ve ikincisi boş mu diye 1/0 yazdır.
Örnek çözümü göster
string { if (!in_array($ext, $allowed, true)) { return ""; } return bin2hex(random_bytes(8)) . "." . $ext; } yaz. "png" geçerli → bin2hex(random_bytes(8)) = 16 hex + ".png" = 20 karakter → strlen 20 = true (1). "exe" geçersiz → boş dize → === "" true (1).
Örnek çözüm:
<?php
function generateUploadName(string $ext, array $allowed): string {
if (!in_array($ext, $allowed, true)) {
return "";
}
return bin2hex(random_bytes(8)) . "." . $ext;
}
$allowed = ["png", "jpg", "pdf"];
$name = generateUploadName("png", $allowed);
$bad = generateUploadName("exe", $allowed);
echo (strlen($name) === 20 ? "1" : "0") . "\n";
echo ($bad === "" ? "1" : "0") . "\n";
Kendini test et
-
Upload güvenlik kavramlarını eşleştir
- finfo
- Gerçek MIME okur
- random_bytes
- Rastgele ad üretir
- bin2hex
- Hex dizeye çevirir
- allowlist
- Uzantı denetimi
-
Yüklenen dosyanın gerçek MIME türünü nasıl okursun?
- $_FILES['file']['type'] ile
- pathinfo() ile
- basename() ile
- finfo sınıfı ile
Cevabı göster
finfo sınıfı ile — Doğru. finfo dosyanın içeriğinden MIME okur; güvenilmez bildirime güvenilmez.
-
random_bytes ile ad üret
$name = bin2hex(____(16)) . ".png";
Cevabı göster
$name = bin2hex(random_bytes(16)) . ".png";
Sıradaki ders: Özet - İleri güvenlik