SQL injection (SQL enjeksiyonu), kullanıcıdan gelen verinin doğrudan SQL sorgusunun içine eklenmesiyle oluşan bir güvenlik açığıdır. Bu açık, yıllardır bilinmesine rağmen hâlâ en ciddi web güvenliği risklerinden biri olarak listelenir.
Sorun nereden kaynaklanır?
Sorgu, kullanıcı girdisi metin olarak birleştirilerek oluşturulduğunda, veritabanı bu girdiyi verinin değil komutun parçası olarak yorumlayabilir. Sonuç; yetkisiz veri okuma, değiştirme veya silme olabilir.
// YANLIŞ: kullanıcı girdisi sorguya metin olarak ekleniyor
var sql = "SELECT * FROM Musteriler WHERE Eposta = '" + eposta + "'";
Çözüm 1: Parametreli sorgular
Parametreli sorgularda değer, sorgudan ayrı gönderilir ve her zaman veri olarak işlenir:
using var cmd = new SqlCommand("SELECT * FROM Musteriler WHERE Eposta = @eposta", baglanti);
cmd.Parameters.Add("@eposta", SqlDbType.NVarChar, 256).Value = eposta;
Çözüm 2: ORM kullanımı
Entity Framework Core gibi ORM'ler LINQ sorgularını otomatik olarak parametreli hale getirir. Ham SQL gerektiğinde de parametreleri doğru işleyen metotlar kullanılmalıdır:
var sonuc = db.Musteriler
.FromSql($"SELECT * FROM Musteriler WHERE Eposta = {eposta}")
.ToList();
Bu kullanımda enterpolasyon değeri parametreye dönüştürülür. Buna karşılık sorgu metnini önceden birleştirip ham SQL metoduna vermek yine risklidir.
Çözüm 3: En az yetki
Uygulamanın veritabanına bağlandığı kullanıcı yalnızca ihtiyaç duyduğu işlemleri yapabilmelidir. Bir web uygulamasının tablo silme veya sunucu ayarlarını değiştirme yetkisine ihtiyacı yoktur. Bir açık olsa bile hasar sınırlı kalır.
Çözüm 4: Girdi doğrulama
Girdi doğrulama tek başına yeterli değildir ama ek bir katmandır: e-posta formatı, sayı aralıkları, izin verilen değer listeleri. Sıralama yönü veya sütun adı gibi parametreleştirilemeyen değerler için mutlaka izin listesi kullanılmalıdır.
Diğer öneriler
- Hata mesajlarında veritabanı ayrıntılarını kullanıcıya göstermeyin. Bkz. .NET'te loglama.
- Kod incelemelerinde metin birleştirerek oluşturulan sorguları arayın.
- Yapay zekâ ile üretilen veritabanı kodunu bu gözle kontrol edin. Bkz. AI ile kod yazarken güvenlik.
- Statik analiz araçlarını CI sürecine ekleyin. Bkz. CI/CD.
Sık sorulan sorular
Saklı yordam (stored procedure) kullanmak yeterli mi?
Saklı yordamlar parametreli çağrıldığında güvenlidir; ancak yordamın içinde dinamik SQL metin birleştirmeyle oluşturuluyorsa aynı risk devam eder.
NoSQL veritabanlarında bu sorun yok mu?
Benzer enjeksiyon türleri NoSQL sorgularında da görülebilir. Temel ilke aynıdır: kullanıcı girdisini komut olarak yorumlatmayın.
Sonuç
SQL injection, doğru alışkanlıklarla tamamen önlenebilen bir açıktır. Mevcut uygulamalarınızın güvenlik incelemesi için iletişime geçebilirsiniz.