PHP'de Form Verileri: POST ve GET ile Alma ve Güvenli Filtreleme Rehberi

Giriş
Web formları aracılığıyla gelen verilerin doğru şekilde alınması, doğrulanması ve filtrelenmesi; uygulama güvenliği, veri bütünlüğü ve kullanıcı deneyimi için kritik öneme sahiptir. Bu rehberde PHP'de POST ve GET ile veri almanın temellerini, yaygın saldırı tiplerini ve güvenli filtreleme/işleme yöntemlerini örneklerle anlatıyorum.

Temel Kavramlar: GET vs POST

  • GET: Veriler URL üzerine eklendiği için (sorgu string), küçük boyutlu, yalın ve paylaşıma uygun veriler için kullanılır. Gizlilik gerektiren veriler için önerilmez.
  • POST: Veriler HTTP gövdesinde gönderilir; daha büyük veri, gizli bilgiler ve form gönderimleri için daha uygundur.
  • $_GET ve $_POST: PHP'de formlardan gelen verilere erişmek için kullanılan süper global dizilerdir. Ayrıca $_REQUEST bu ikisini birleştirir ama hangi kaynaktan geldiği belirsiz olacağından tavsiye edilmez.

Güvenlik Tehditleri - Kısa Özet

  • XSS (Cross-Site Scripting): Kullanıcı girdisi, çıktıya olduğu gibi yazıldığında çalıştırılabilir Javascript eklenmesi.
  • SQL Injection: Doğrulanmamış verinin SQL sorgusuna doğrudan eklenmesiyle veri sızıntısı veya manipülasyon.
  • CSRF (Cross-Site Request Forgery): Yetkili bir kullanıcının bilgisi dışında istek yaptırılması.
  • Dosya Yükleme Güvenlik Riskleri: Zararlı dosyaların sunucuya yüklenmesi ve çalıştırılması.

Form Verilerini Güvenli Şekilde Alma: Adım Adım

1) İstek Metodunu Kontrol Et

Form verilerini işlerken ilk adım, beklenen HTTP metodunu doğrulamaktır:

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // POST işlemleri
}

2) Ham Veriyi Alma ve Temizleme

Ham kullanıcı girdisini doğrudan kullanmayın. Önce boşlukları kırpın, sonra uygun bir sanitizasyon uygulayın.

// Güvenli örnek: isim alanını al ve HTML özel karakterlerini temizle
$name = trim($_POST['name'] ?? '');
$name = filter_var($name, FILTER_SANITIZE_FULL_SPECIAL_CHARS);

// E-posta doğrulama örneği
$email = trim($_POST['email'] ?? '');
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // Geçersiz e-posta
}

Not: Sanitizasyon, veriyi "temizler"; doğrulama (validation) ise verinin beklenen formatta olup olmadığını kontrol eder. Her iki adımı da uygulayın.

3) Veri Tabanına Kaydetmeden Önce: Hazırlanmış İfadeler (Prepared Statements)

SQL enjeksiyonlarını engellemenin en etkili yolu, parametreli sorgular kullanmaktır. PDO örneği:

// PDO ile prepared statement
$pdo = new PDO('mysql:host=localhost;dbname=app;charset=utf8mb4', 'kullanici', 'sifre', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
$stmt->execute([':name' => $name, ':email' => $email]);

4) Çıktıya Yazmadan Önce Kaçış (Escape) İşlemi

Kullanıcı verisini HTML içinde gösterirken XSS'i önlemek için mutlaka kaçış uygulayın:

// Güvenli çıktı
echo htmlspecialchars($name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');

5) CSRF Koruması

Formunuza bir CSRF token ekleyin. Token'ı session'da saklayın ve gönderilen token ile eşleşmeyi doğrulayın.

// Token üretme (form gösterilirken)
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// Formda gizli alan: <input type="hidden" name="csrf_token" value="{$_SESSION['csrf_token']}">

// İşleme sırasında doğrulama
if (!hash_equals($_SESSION['csrf_token'] ?? '', $_POST['csrf_token'] ?? '')) {
    // Geçersiz token: isteği reddet
}

6) Dosya Yüklemelerinde Dikkat Edilecekler

  • Dosya tipini MIME türüyle ve finfo ile kontrol edin.
  • Kaydetmeden önce rastgele bir dosya adı verin ve mümkünse webroot dışında depolayın.
  • Boyut limitleri uygulayın ve uzantıya göre çalıştırma izni vermeyin.

Pratik Örnek Akış

  • İstek geldiğinde metod kontrolü
  • CSRF kontrolü
  • Alan bazlı trim + sanitizasyon + doğrulama
  • Hazırlanmış sorguyla veri tabanına kayıt
  • Çıktıda htmlspecialchars ile kaçış

Kısa Güvenlik Kontrol Listesi (Checklist)

  • Her zaman server-side (sunucu tarafı) doğrulama yapın.
  • SQL sorguları için prepared statements kullanın (PDO/mysqli).
  • Çıktıda htmlspecialchars ile XSS'i engelleyin.
  • Formlar için CSRF token zorunlu kılın.
  • Dosya yüklemelerinde MIME ve boyut kontrolü uygulayın.
  • Tüm hassas aktarım için HTTPS kullanın.
  • Girdi doğrulama kurallarını (ör. regex, min/max uzunluk) açık ve net tutun.

Sonuç

Form verilerini almak sadece $_POST veya $_GET dizilerine erişmekten ibaret değildir; veri akışının her aşamasında doğrulama, sanitizasyon ve uygun güvenlik önlemleri uygulanmalıdır. Bu rehberdeki adımlar —metod kontrolü, alan bazlı temizleme, sunucu tarafı doğrulama, prepared statements, çıktıda kaçış, CSRF koruması ve dosya yükleme kontrolleri— uygulamanızı hem daha güvenli hem de sürdürülebilir hale getirecektir.

Uygulamanızın ihtiyaçlarına göre bu yapı taşlarını bir araya getirerek, kullanıcı verilerini güvenle işleyen ve saldırılara dayanıklı bir form işleme akışı kurabilirsiniz. Geliştirme ve test süreçlerinde otomatik güvenlik taramaları ve manuel kod incelemeleriyle süreçleri desteklemeyi unutmayın.