SQL Enjeksiyonu (SQL Injection) Nedir?
Kısa tanım
SQL enjeksiyonu (SQL injection), bir uygulamanın kullanıcıdan gelen veriyi SQL sorgusunun metnine doğrudan eklemesi sonucunda bu verinin sorgunun anlamını değiştirebilmesine yol açan güvenlik açığıdır. Veri sızıntısına, kayıtların değiştirilmesine ya da silinmesine ve kimlik doğrulamanın atlatılmasına neden olabilir. Temel önlem, değerleri sorgu metninden ayrı gönderen parametreli sorgular (prepared statements) kullanmaktır.
Diğer adları: SQL Injection, SQLi, SQL enjeksiyon saldırısı, SQL injection açığı

Kod ile verinin birbirine karışması
Bir SQL sorgusu, veritabanı için çalıştırılacak bir koddur. Uygulama kullanıcıdan gelen değeri bu kodun içine düz metin olarak yapıştırdığında, veritabanı hangi kısmın geliştiricinin yazdığı komut, hangisinin kullanıcı verisi olduğunu ayırt edemez. Değer, tırnak işareti gibi SQL için anlamlı karakterler içerdiğinde sorgunun yapısı değişebilir. SQL enjeksiyonunun bütün türleri bu tek kök nedenden doğar: veri ile kodun aynı kanaldan taşınması.
Güvensiz ve güvenli sorgu
// Güvensiz: değer sorgu metnine yapıştırılıyor
const sonuc = await db.query(
"SELECT id, tutar FROM siparisler WHERE musteri_eposta = '" + eposta + "'"
);
// Güvenli: değer sorgudan ayrı, parametre olarak gönderiliyor
const sonuc = await db.query(
"SELECT id, tutar FROM siparisler WHERE musteri_eposta = $1",
[eposta]
);İkinci örnekte veritabanı önce sorgunun yapısını ayrıştırır, değer ise sonradan ve yalnızca veri olarak yerine konur. eposta değişkeni ne içerirse içersin sorgunun anlamını değiştiremez; en kötü ihtimalle hiçbir kayıtla eşleşmeyen tuhaf bir e-posta adresi olarak değerlendirilir. Yer tutucu sözdizimi sürücüye göre değişir ($1, ?, :eposta), ilke aynıdır.
Etkisi neden bu kadar geniş?
Başarılı bir enjeksiyon, uygulamanın veritabanı kullanıcısının yapabildiği her şeyi saldırgana açabilir: başka tablolardaki müşteri ve parola özeti kayıtlarını okumak, fiyatları ya da yetkileri değiştirmek, verileri silmek ve kimlik doğrulama sorgusunu atlatmak. Sonuç ekranda hiç görünmese bile, yanıt süresindeki ya da davranıştaki farklardan veri sızdırılabildiği "kör" (blind) türler vardır; yani "hata mesajı göstermiyoruz" demek açığı kapatmaz. Enjeksiyon, OWASP Top 10 listesinde Injection kategorisi altında yer alan, uzun yıllardır bilinen ama hâlâ bulunan bir güvenlik açığı türüdür.
Parametrelerin yetmediği yerler
Tablo ve sütun adları, ORDER BY yönü gibi sorgu parçaları parametre olarak gönderilemez. Bu durumda kullanıcı girdisi sorguya hiç girmemeli; koddaki sabit bir izin listesinden seçim yapılmalıdır:
const siralamaSutunlari = { tarih: "olusturma_tarihi", tutar: "toplam_tutar" };
const sutun = siralamaSutunlari[istek.sirala] ?? "olusturma_tarihi";
const yon = istek.yon === "artan" ? "ASC" : "DESC";ORM kullanmak varsayılan olarak parametreli sorgu üretir, ama ham SQL yardımcılarına dize birleştirmeyle değer vermek riski geri getirir. Aynı şekilde, kendi içinde dinamik SQL üreten saklı yordamlar da güvenli kabul edilemez. Kullanıcı girdisini elle kaçışlamak (escaping) ise kırılgan bir yöntemdir; OWASP SQL enjeksiyonu önleme rehberinde bunu önermez.
Ek savunma katmanları
- En az yetki: Uygulamanın veritabanı kullanıcısı tablo silemez, şema değiştiremez ve yalnızca ihtiyaç duyduğu tablolara erişir. En az yetki ilkesi, bir açığın hasarını sınırlar.
- Hata mesajlarını gizlemek: Ham veritabanı hataları kullanıcıya değil, günlüklere gitmelidir.
- Girdi doğrulama: Kimlik numarasının sayı, tarihin tarih olduğunu doğrulamak saldırı yüzeyini daraltır; ancak parametreli sorgunun yerini tutmaz.
- WAF ve tarama araçları: Bilinen kalıpları yakalayabilir; kodu düzeltmenin alternatifi değil, tamamlayıcısıdır.

