Hızlı cevap: SQL injection (SQLi), kullanıcıdan gelen bir girdinin veri tabanı sorgusuna karışıp sorgunun mantığını değiştirmesidir. Saldırgan, bir arama kutusuna ya da URL parametresine özel karakterler yazarak uygulamanın adına veri tabanına kendi komutunu çalıştırabilir: tüm kullanıcı tablosunu çekmek, parola özetlerini almak, hatta veriyi silmek. Onlarca yıldır bilinmesine rağmen hâlâ en yaygın kritik açıklardan biridir ve OWASP Top 10'da Injection başlığı altındadır. Tek ve kesin çözüm parametreli sorgulardır (prepared statements): girdi asla sorgu metnine yapıştırılmaz, ayrı bir parametre olarak gönderilir. Girdiyi elle temizlemeye çalışmak güvenilmez bir yamadır, asıl çözüm değildir.

Bir web uygulamasının en eski ve en tehlikeli açığı hâlâ ayakta: SQL injection. İlk tanımlanmasının üzerinden yirmi yılı aşkın süre geçti ama bugün bile veri ihlallerinin önemli bölümü bu yolla başlıyor. Sebebi teknik değil kültürel: doğru korunma yöntemi basit ve bilinen olmasına rağmen, hâlâ yanlış yazılan kod üretiliyor. Bu yazı, SQL injection'ın nasıl çalıştığını ve kesin çözümünü anlatıyor.

SQL injection nasıl çalışır

Bir uygulama, kullanıcı adını kontrol etmek için şöyle bir sorgu kurduğunu düşünün. Girdiyi doğrudan metne yapıştırıyor:

SELECT * FROM kullanicilar WHERE ad = 'girdi' AND parola = 'girdi2'

Kullanıcı, ad alanına normal bir metin yerine şunu yazarsa:

' OR '1'='1

Sorgu şuna dönüşür:

SELECT * FROM kullanicilar WHERE ad = '' OR '1'='1' AND parola = ''

'1'='1' her zaman doğru olduğu için koşul sağlanır ve saldırgan parola bilmeden giriş yapabilir. Bu en basit örnektir. Gerçek saldırılar tüm tabloları çekmek, başka tabloları birleştirmek (UNION) ya da veri tabanı sürümünü öğrenmek için çok daha karmaşık girdiler kullanır.

Sorunun kökü tek bir hatadır: veri (kullanıcı girdisi) ile kod (SQL komutu) aynı metin dizesine karışıyor. Veri tabanı, nerede komutun bittiğini nerede verinin başladığını ayırt edemiyor.

SQL injection türleri

Tür Nasıl işler Fark eden yön
Klasik (in band) Sonuç doğrudan sayfada görünür En kolay tespit ve istismar
Kör (blind) Sonuç görünmez, doğru/yanlış davranıştan çıkarılır Yavaş ama etkili
Zaman tabanlı kör Sorguya gecikme enjekte edilir, yanıt süresinden okunur Hiçbir çıktı olmadan çalışır
Hata tabanlı Veri tabanı hata mesajından bilgi sızar Ayrıntılı hata açıksa çok verimli
Out of band Veri, DNS ya da HTTP ile dışarı sızdırılır İzole ortamlarda kullanılır

Bu çeşitlilik önemlidir çünkü "sayfada hata görmüyorum, demek ki güvenliyim" düşüncesi yanlıştır. Kör ve zaman tabanlı teknikler hiçbir görünür belirti olmadan çalışır.

Kesin çözüm: parametreli sorgular

SQL injection'ın tek gerçek çözümü, veriyi koddan ayırmaktır. Bu, parametreli sorgular (prepared statements) ile yapılır. Sorgu şablonu ve veri ayrı gönderilir, veri tabanı veriyi asla komut olarak yorumlamaz.

Yanlış (girdi metne yapıştırılıyor):

"SELECT * FROM kullanicilar WHERE ad = '" + girdi + "'"

Doğru (girdi parametre olarak gönderiliyor):

"SELECT * FROM kullanicilar WHERE ad = ?"   // sonra girdi ayrı parametre

Bu yaklaşımda saldırgan ne yazarsa yazsın, girdi yalnızca bir değer olarak ele alınır, asla sorgunun yapısını değiştiremez. Modern her veri tabanı kütüphanesi ve ORM bunu destekler. Doğru kullanılan bir ORM, SQL injection'a karşı büyük ölçüde koruma sağlar.

Neden elle temizleme yetmez

Yaygın bir yanlış, girdideki tehlikeli karakterleri (tırnak gibi) elle silmeye çalışmaktır. Bu güvenilmezdir çünkü:

  • Farklı veri tabanlarının farklı kaçış kuralları vardır.
  • Karakter kodlama farkları filtreyi atlatabilir.
  • Sayısal alanlar tırnak gerektirmediği için bu tür filtreler onları kaçırır.

Elle temizleme bir savunma katmanı olabilir ama tek başına asla yeterli değildir. Asıl çözüm parametreli sorgudur.

Derinlemesine savunma

Parametreli sorgu birincil savunmadır, ama kritik sistemlerde katmanlı korunma gerekir:

  • En az yetki. Uygulamanın veri tabanı kullanıcısı yalnızca ihtiyaç duyduğu işlemlere yetkili olmalı. Bir açık bulunsa bile hasar sınırlı kalır.
  • Girdi doğrulama. Beklenen biçime uymayan girdiyi baştan reddedin. Bu, parametreli sorgunun yerini tutmaz ama ek katmandır.
  • Web Application Firewall (WAF). Bilinen enjeksiyon desenlerini yakalar. Yardımcıdır, kök çözüm değildir, atlatılabilir.
  • Hata mesajlarını gizleme. Ayrıntılı veri tabanı hataları saldırgana yol gösterir. Üretimde jenerik hata gösterin.
  • Kayıt ve izleme. Anormal sorgu desenleri izlenmeli. Bu, SIEM ve SOC yaklaşımının parçasıdır.

SQL injection, OWASP Top 10 Injection kategorisinin en bilinen örneğidir; genel çerçeve için OWASP Top 10 rehberi yazımıza bakabilirsiniz. Aynı kategorideki bir başka açık için XSS yazımıza bakın.

Uygulamanız güvenli mi, nasıl doğrularsınız

Kod güvenli görünse bile tek bir gözden kaçmış sorgu tüm sistemi açar. Doğrulamanın tek güvenilir yolu test etmektir:

  • Kod incelemesi. Tüm veri tabanı erişimlerinin parametreli olduğunu doğrulayın.
  • Statik analiz. Otomatik araçlar birleştirilmiş sorguları işaretler.
  • Yetkili sızma testi. Gerçek bir saldırgan gibi denenmesi, kalan açığı ortaya çıkarır. Kapsam için sızma testi süreci yazımıza bakabilirsiniz.

Sık sorulan sorular

SQL injection hâlâ neden yaygın? Çözüm bilinmesine rağmen yanlış kod yazılmaya devam ediyor. Eski sistemler, aceleyle yazılan kod ve eğitim eksikliği başlıca sebepler.

ORM kullanıyorum, güvenli miyim? Büyük ölçüde, ancak ORM'in ham sorgu (raw query) özelliğini kullanırken aynı hataya düşebilirsiniz. ORM'i doğru kullanmak şarttır.

WAF beni korur mu? Kısmen. WAF bilinen desenleri yakalar ama atlatılabilir. Kök çözüm parametreli sorgudur, WAF ek katmandır.

Kör SQL injection tehlikeli mi? Evet. Çıktı görünmese de saldırgan doğru/yanlış yanıtlardan ya da gecikmeden veriyi tek tek çıkarabilir.

Sayısal alanlar güvenli mi? Hayır. Sayısal parametreler tırnak gerektirmediği için bazı filtreler onları kaçırır. Parametreli sorgu burada da şarttır.

SQL injection ile veri silinebilir mi? Veri tabanı kullanıcısının yetkisi varsa evet. En az yetki ilkesi bu yüzden kritiktir.

Kaynaklar

Uygulamanızın SQL injection'a karşı gerçekten dayanıklı olup olmadığını ölçmek isterseniz DSET ile iletişime geçin. Ankara Hacettepe Teknokent laboratuvarımızdan sızma testi, güvenli kod incelemesi ve geliştirici eğitimi hizmeti veriyoruz.