CodeBlanks Logo Icon CodeBlanks

Secure file upload

PHP kursu · Uzman · Ders 34/54

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

  1. 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
  2. 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.

  3. random_bytes ile ad üret

    $name = bin2hex(____(16)) . ".png";
    Cevabı göster
    $name = bin2hex(random_bytes(16)) . ".png";

Uzman bölümündeki tüm dersler