Doğrulama sınırını doğru belirleyin
API’ye gelen her veri güvenilmez kabul edilmelidir. İstemci tarafındaki HTML/JavaScript doğrulaması yalnızca kullanıcı deneyimini iyileştirir; güvenlik ve veri bütünlüğü için asıl kontrol sunucu tarafında yapılmalıdır.
Önerilen akış:
Okunabilir ve güvenli doğrulama
Doğrulama kurallarını denetleyici koduna dağınık biçimde yazmak yerine ayrı bir şema, DTO veya doğrulayıcı sınıfında toplamak bakım ve test kolaylığı sağlar. Aşağıdaki PHP örneği, JSON gövdesini doğrulayan basit bir yaklaşım gösterir:
Bu örnekte parola asla loglanmamalı veya hata yanıtında geri gönderilmemelidir. E-posta adresi gibi kişisel veriler de gereksiz yere loglara yazılmamalıdır. SQL sorgularında parametreli ifadeler, HTML çıktısında bağlama uygun kaçışlama, dosya yüklemelerinde ise MIME türü ve boyut kontrolü kullanılmalıdır. Doğrulama, SQL injection veya XSS korumasının yerine geçmez; her çıktı ve veri erişim katmanının kendi güvenlik önlemi bulunmalıdır.
JavaScript, Python veya C# tarafında da aynı ayrım korunabilir: giriş şeması, iş kuralları ve kalıcı veri erişimi ayrı katmanlarda tutulmalıdır. Örneğin Python’da Pydantic, C#’ta DataAnnotations veya FluentValidation kullanılabilir; ancak kütüphanenin varsayılan davranışı incelenmeden kritik güvenlik kararı verilmemelidir.
Tutarlı hata sözleşmesi oluşturun
İstemcinin hatayı güvenilir biçimde işlemesi için tüm uç noktalar benzer bir yanıt biçimi kullanmalıdır. Örneğin:
Kimlik doğrulama hatalarında hesap varlığını açığa çıkaran ayrıntılı mesajlardan kaçının. Yetkisiz istekler için 401, kimliği doğrulanmış ancak yetkisi olmayan istekler için 403, biçimsel veya anlamsal doğrulama sorunları için 400 ya da 422 kullanılabilir. Veritabanı bağlantı hatası, stack trace veya iç servis ayrıntıları son kullanıcıya gönderilmemelidir; bunlar sunucu tarafında güvenli loglama ve korelasyon kimliğiyle izlenmelidir.
Test edilebilirlik ve kontrol listesi
Doğrulayıcılar mümkün olduğunca saf fonksiyonlar olarak tasarlanırsa birim testleri kolaylaşır. En az şu durumları test edin:
API’ye gelen her veri güvenilmez kabul edilmelidir. İstemci tarafındaki HTML/JavaScript doğrulaması yalnızca kullanıcı deneyimini iyileştirir; güvenlik ve veri bütünlüğü için asıl kontrol sunucu tarafında yapılmalıdır.
Önerilen akış:
- İstek gövdesi, sorgu parametreleri ve başlıklar ayrıştırılır.
- Alanların türü, uzunluğu, biçimi ve zorunluluğu kontrol edilir.
- İş kuralı doğrulaması yapılır. Örneğin stokta olmayan ürün satın alınamaz.
- Veri, veritabanına veya başka bir servise gönderilmeden önce normalize edilir.
- Başarısızlıklar güvenli ve tutarlı bir hata biçiminde döndürülür.
Okunabilir ve güvenli doğrulama
Doğrulama kurallarını denetleyici koduna dağınık biçimde yazmak yerine ayrı bir şema, DTO veya doğrulayıcı sınıfında toplamak bakım ve test kolaylığı sağlar. Aşağıdaki PHP örneği, JSON gövdesini doğrulayan basit bir yaklaşım gösterir:
php
$payload = json_decode($request->getContent(), true);
if (!is_array($payload)) {
return errorResponse(400, 'INVALID_JSON', 'Geçersiz JSON gövdesi.');
}
$email = filter_var($payload['email'] ?? null, FILTER_VALIDATE_EMAIL);
$password = $payload['password'] ?? null;
$errors = [];
if ($email === false) {
$errors['email'] = 'Geçerli bir e-posta adresi girin.';
}
if (!is_string($password) || strlen($password) < 12 || strlen($password) > 128) {
$errors['password'] = 'Parola 12-128 karakter arasında olmalıdır.';
}
if ($errors !== []) {
return validationErrorResponse($errors);
}
Bu örnekte parola asla loglanmamalı veya hata yanıtında geri gönderilmemelidir. E-posta adresi gibi kişisel veriler de gereksiz yere loglara yazılmamalıdır. SQL sorgularında parametreli ifadeler, HTML çıktısında bağlama uygun kaçışlama, dosya yüklemelerinde ise MIME türü ve boyut kontrolü kullanılmalıdır. Doğrulama, SQL injection veya XSS korumasının yerine geçmez; her çıktı ve veri erişim katmanının kendi güvenlik önlemi bulunmalıdır.
JavaScript, Python veya C# tarafında da aynı ayrım korunabilir: giriş şeması, iş kuralları ve kalıcı veri erişimi ayrı katmanlarda tutulmalıdır. Örneğin Python’da Pydantic, C#’ta DataAnnotations veya FluentValidation kullanılabilir; ancak kütüphanenin varsayılan davranışı incelenmeden kritik güvenlik kararı verilmemelidir.
Tutarlı hata sözleşmesi oluşturun
İstemcinin hatayı güvenilir biçimde işlemesi için tüm uç noktalar benzer bir yanıt biçimi kullanmalıdır. Örneğin:
json
{
"type": "https://api.example.com/errors/validation",
"title": "Doğrulama hatası",
"status": 422,
"code": "VALIDATION_ERROR",
"errors": {
"email": "Geçerli bir e-posta adresi girin.",
"password": "Parola 12-128 karakter arasında olmalıdır."
},
"requestId": "8f3c2a10"
}
Kimlik doğrulama hatalarında hesap varlığını açığa çıkaran ayrıntılı mesajlardan kaçının. Yetkisiz istekler için 401, kimliği doğrulanmış ancak yetkisi olmayan istekler için 403, biçimsel veya anlamsal doğrulama sorunları için 400 ya da 422 kullanılabilir. Veritabanı bağlantı hatası, stack trace veya iç servis ayrıntıları son kullanıcıya gönderilmemelidir; bunlar sunucu tarafında güvenli loglama ve korelasyon kimliğiyle izlenmelidir.
Test edilebilirlik ve kontrol listesi
Doğrulayıcılar mümkün olduğunca saf fonksiyonlar olarak tasarlanırsa birim testleri kolaylaşır. En az şu durumları test edin:
- Geçerli istek beklenen DTO veya modele dönüşüyor mu?
- Eksik, boş, yanlış türde ve sınır uzunlukta alanlar reddediliyor mu?
- Bilinmeyen alanlar reddediliyor veya açık bir politikayla yok sayılıyor mu?
- Yetkisiz kullanıcı başka bir kullanıcının kaydına erişemiyor mu?
- Hatalı JSON, aşırı büyük gövde ve beklenmeyen içerik türü güvenle işleniyor mu?
- Hata yanıtı gizli veri, stack trace veya parola içeriyor mu?