Konuyu Okuyanlar: 1 Ziyaretçi

Dosya Yükleme File Upload Açıkları ve Güvenli Doğrulama Rehberi

Dosya Yükleme File Upload Açıkları ve Güvenli Doğrulama Rehberi
[center]
[Resim: attachment.php?aid=168]
[/center]

Selam TurkTeam, BlueTornado ile devam.

Dosya yükleme özelliği; profil fotoğrafı, ek, CV, fatura gibi meşru ihtiyaçlar için vardır. Yanlış uygulanırsa webshell yükleme, XSS (SVG/HTML), path traversal, depolama tüketimi (DoS) ve sunucu tarafı parse açıklarına yol açar. Bu rehber güvenli doğrulama odaklıdır; örnekler DVWA ve kendi labınız içindir.

Konuda Anlatılacaklar
  1. File upload riskleri nelerdir?
  2. DVWA File Upload labı
  3. Tehlikeli doğrulama hataları
  4. Savunma katmanları: tip, içerik, depolama, sunum
  5. Uygulamalı güvenli tasarım
  6. İleri seviye: SVG, zip slip, malware tarama
  7. Kaynakça ve yasal uyarı

1) Riskler
  • Uzaktan kod çalıştırma:
    Kod:
    .php
    ,
    Kod:
    .jsp
    ,
    Kod:
    .aspx
    webshell'in web köküne yazılması
  • XSS:
    Kod:
    .html
    /
    Kod:
    .svg
    dosyasının aynı origin'den sunulması
  • Path traversal:
    Kod:
    ../../var/www/shell.php
    dosya adı
  • Overwrite: mevcut kritik dosyanın üzerine yazma
  • Zip Slip: arşiv açarken dizin kaçışı
  • DoS: çok büyük dosya, zip bomb

OWASP WSTG içinde "Testing for Uploaded File Attacks" bölümü bu aileyi kapsar. CWE örnekleri: CWE-434 (Unrestricted Upload of File with Dangerous Type).

2) Lab: DVWA File Upload
Kod:
docker compose -f DVWA/docker-compose.yml up -d # Security Low -> File Upload

Low seviyede çoğu kurulum yalnızca istemci tarafı veya basit uzantı kontrolü yapar. Impossible seviyede içerik tipi ve depolama sertleştirmesi vardır.

[center][/center]

Gözlem adımları (lab):
Kod:
# 1) Küçük bir PNG yükleyin, yükleme yolunu not alın # 2) Uzantı / Content-Type oyunlarını lab politikasına göre gözlemleyin # 3) Impossible ile farkı karşılaştırın

Webshell yüklemeyi üretimde veya izinsiz sistemlerde denemeyin. Labda bile yüklediğiniz dosyaları işiniz bitince silin.

3) Yaygın Hatalı Kontroller

Sadece istemci tarafı:
Kod:
<!-- Kolayca bypass: DevTools ile accept kaldırma --> <input type="file" accept="image/*">

Sadece uzantı kara listesi:
Kod:
# .php engelli ama .php5 .phtml .phar .jpg.php ? # Sunucu yapılandırmasına bağlı

Sadece Content-Type başlığı:
Kod:
Content-Type: image/png # İstemci istediğini yazar; güvenilmez

MIME sniffing/
Kod:
file
komutu tek başına:
Polyglot dosyalar (hem geçerli görüntü hem script) tarih boyunca görülmüştür; yine de sunucu tarafı MIME tahmini + uzantı allowlist birlikte kullanılmalıdır.

4) Güvenli Doğrulama Katmanları

1 - Allowlist: Yalnızca iş ihtiyacı olan uzantılar (
Kod:
jpg jpeg png webp pdf
).

2 - Rastgele dosya adı: Kullanıcı adını kullanmayın.

Kod:
import uuid from pathlib import PurePosixPath ext = PurePosixPath(filename).suffix.lower() if ext not in {".jpg", ".jpeg", ".png", ".webp"}: raise ValueError("uzantı yok") stored = f"{uuid.uuid4().hex}{ext}"

3 - İçerik doğrulama:
Kod:
from PIL import Image img = Image.open(upload_stream) img.verify() # bozuk/şüpheli dosyayı ele # Yeniden encode ederek metadata/polyglot riskini azaltın Image.open(upload_stream).save(out_path, format="JPEG")

4 - Depolama konumu: Dosyaları web kökü dışına veya yalnızca statik object storage'a koyun. Uygulama sunucusunun yorumladığı dizine yazmayın.

5 - Sunum:
Kod:
# İndirme için Content-Disposition: attachment; filename="rapor.pdf" X-Content-Type-Options: nosniff Content-Type: application/pdf
SVG/HTML'i aynı origin'de inline açmayın; mümkünse ayrı domain (static.example) kullanın.

6 - Boyut ve hız sınırı:
Kod:
# Nginx örneği client_max_body_size 5m;

[center][/center]

5) Uygulamalı Güvenli İskelet
Kod:
# Flask kavramsal özet ALLOWED = {"jpg", "jpeg", "png"} MAX = 5 * 1024 * 1024 def save_avatar(file_storage): if file_storage.content_length and file_storage.content_length > MAX: abort(400) name = file_storage.filename or "" ext = name.rsplit(".", 1)[-1].lower() if ext not in ALLOWED: abort(400) # PIL verify + re-encode # kaydet: /var/app/uploads/{uuid}.jpg (web root dışı) # sun: imza/lı URL veya ayrı static host

Kod:
# PHP move_uploaded_file + finfo allowlist (kavramsal) $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($_FILES['u']['tmp_name']); $allowed = ['image/jpeg' => 'jpg', 'image/png' => 'png']; if (!isset($allowed[$mime])) { http_response_code(400); exit; }

6) İleri Seviye
SVG: İçinde JavaScript / external entity olabilir. Avatar için SVG kabul etmeyin veya sıkı sanitizer + ayrı domain kullanın.

Zip Slip:
Kod:
# Tehlikeli arşiv girdileri ../../../../tmp/evil # Açarken final path'in hedef dizin altında kaldığını doğrulayın

Malware tarama: ClamAV vb. ile async tarama; temizlenmeden public yapmayın.

ImageMagick / parse CVE'leri: Görüntü işleme kütüphanelerini güncel tutun; policy.xml ile coder'ları kısıtlayın. İcat CVE numarası yazmayın; NVD'den doğrulayın.

Kod:
# Rapor dili Bulgu: Unrestricted File Upload (CWE-434) Kanıt: Labda tehlikeli tipin web köküne yazılması Öneri: allowlist + re-encode + web root dışı + nosniff

[center][/center]

7) Sonuç
Dosya yükleme, "uzantıya bakmak"tan ibaret değildir. Allowlist, içerik doğrulama, güvenli depolama ve güvenli sunum birlikte gerekir. DVWA Low/Impossible farkını inceleyerek kendi uygulamanızın kontrol listesini çıkarın.



Ek: Operasyonel Kontrol Listesi ve Yaygın Senaryolar
Profil fotoğrafı: Yalnızca raster; yeniden encode; sabit max boyut (ör. 1024px); EXIF temizliği (konum sızıntısı).

Kod:
# ImageMagick (güncel sürüm + policy) ile yeniden örnekleme kavramı # convert input.jpg -resize 1024x1024> -strip out.jpg

PDF yükleme: PDF içinde JavaScript / form aksiyonları olabilir. Inline göstermek yerine
Kod:
Content-Disposition: attachment
veya güvenilir bir önizleme servisi kullanın.

Çok parçalı / chunked upload: Her parçayı ayrı doğrulayın; birleştirme sonrası tekrar MIME/uzantı kontrolü yapın; geçici dosyaları güvenli dizinde tutun.

Kod:
# S3 / MinIO politikası kavramı # public-read vermeyin; pre-signed URL ile süreli erişim # bucket'ta website hosting açıkken html/svg yüklemeyin

CI kontrolü: Yükleme ile ilgili birim testleri: path traversal dosya adı reddi, aşırı boyut reddi, yanlış MIME reddi, başarılı PNG yolu.

[center][/center]

Yükleme özelliği ürün için vazgeçilmezse, güvenlik bütçesini "sonra bakarız"a bırakmayın; tasarım aşamasında depolama ve sunum kararlarını kilitleyin.

Kaynakça
Yasal Uyarı
Zararlı dosya yükleme ve webshell denemeleri yalnızca kendi labınızda veya yazılı yetki ile yapılmalıdır. İzinsiz yükleme TCK 243-245 kapsamında suçtur. Eğitim amaçlıdır; sorumluluk uygulayana aittir.

Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).


Ek DosyalarEkran Görüntüleri
   
Cevapla



Hızlı Menü: