İçeriğe atla
Makale

SQL Injection (SQLi) Nedir? Türleri ve Nasıl Önlenir?

SQL injection, kullanıcı girdisinin sorguya karışmasıyla veritabanını açığa çıkarır. Türlerini, MOVEit örneğini, önleme ve tespit yollarını anlattık.

Oğuzhan Gerçek··7 dk okuma
SQL Injection (SQLi) Nedir? Türleri ve Nasıl Önlenir?

Kısa cevap: SQL injection (SQL enjeksiyonu, kısaca SQLi), kullanıcı girdisinin bir SQL sorgusuna karışıp sorgunun anlamını değiştirdiği güvenlik açığıdır. Saldırgan bu yolla yetkisi olmayan veriyi okuyabilir, kimlik doğrulamayı aşabilir, kayıtları değiştirip silebilir. Açık sınıfı yirmi yıldır biliniyor, ama 2025 CWE Top 25 listesinde hâlâ ikinci sırada. Kalıcı çözüm, değeri sorguya ayrı bir parametre olarak gönderen parametreli sorgudur (prepared statement); en az yetki, izin listesi, WAF ve düzenli test onu tamamlar.

SQL injection nedir?

OWASP'ın tanımıyla SQL injection saldırısı, istemciden gelen girdi verisiyle uygulamaya bir SQL sorgusu sokulmasıdır. MITRE'nin CWE-89 kaydına göre açık, ürünün SQL komutunu dışarıdan etkilenen girdiyle kurup komutun anlamını değiştirebilecek özel öğeleri hiç ya da doğru biçimde etkisizleştirmemesinden doğar. SQL'in temelleri SQL yazımızda, veritabanı teriminin tanımı sözlüğümüzde.

SQL injection nasıl çalışır?

Açık veren uygulama, veritabanına gönderdiği sorguyu sabit bir metinle kullanıcıdan gelen değeri birleştirerek kurar; arama kutusuna yazılan kelime böylece sorgunun parçası olur. OWASP'a göre açığın iki koşulu var: veri güvenilmeyen bir kaynaktan gelir ve sorguyu dinamik olarak kurmakta kullanılır. Girdideki SQL söz dizimi ayıklanmaz ya da tırnağa alınmazsa CWE-89'a göre sorgu bu girdiyi veri değil, SQL olarak yorumlayabilir; Microsoft'a göre veritabanı motoru da söz dizimi geçerli her sorguyu çalıştırır.

SQL injection türleri

OWASP'ın test rehberi WSTG, saldırıları verinin saldırgana ulaştığı yola göre üçe ayırıyor:

  • In-band: Veri, saldırı girdisinin gönderildiği kanaldan alınır ve doğrudan sayfada görünür. Hata mesajından bilgi toplayan hata tabanlı (error-based) ve iki sorgunun sonucunu birleştiren UNION tabanlı teknikler bu yolu kullanır.
  • Kör (blind): Veri aktarılmaz; saldırgan bilgiyi veritabanının davranışından çıkarır. Boolean tabanlı teknikte ipucu sayfa içeriğindeki fark, zaman tabanlı teknikte cevabın gecikmesidir.
  • Out-of-band: Veri başka bir kanaldan, örneğin bir e-postayla alınır.

OWASP'a göre kör saldırıya çoğu zaman, uygulama genel hata mesajı gösterdiği hâlde açık veren kod düzeltilmediğinde başvurulur. Hata mesajını gizlemek açığı kapatmaz; CWE-89 yine de mesajda yalnız hedef kitleye yarayan en az ayrıntıyı öneriyor.

SQL injection'ın etkileri

CWE-89 ve OWASP, başarılı bir saldırının sonuçlarını şöyle sıralıyor:

  • Veri sızıntısı: Veritabanları çoğunlukla hassas veri tuttuğu için gizlilik kaybı sık görülür.
  • Kimlik doğrulamayı aşma: Parola kontrolü kötü kurulmuş bir sorguyla yapılıyorsa saldırgan, parolayı bilmeden başka bir kullanıcı olarak bağlanabilir (brute force yazımız).
  • Veriyi değiştirme ve silme: Kayıtlar değiştirilebilir, hatta silinebilir; yetki bilgisi veritabanında tutuluyorsa erişim kuralları da yeniden yazılabilir.
  • Sunucuya uzanma: OWASP'a göre veritabanında yönetim işlemi yapmak, sunucudaki dosyaların içeriğini okumak, bazı durumlarda işletim sistemine komut göndermek de mümkün.

SQL injection neden hâlâ gündemde?

OWASP Top 10:2025 listesinde Injection, 2021'deki üçüncü sıradan beşinciye (A05:2025) indi; kategori XSS'i de kapsıyor. OWASP'a göre uygulamaların %100'ü bir tür injection için test edildi; SQL injection seyrek görülen ama etkisi yüksek bir açık ve 14 binden fazla CVE kaydıyla ilişkili.

11 Aralık 2025'te yayımlanan 2025 CWE Top 25 listesinde CWE-89 ikinci sırada, 2024'te üçüncüydü; CWE programına göre liste, 1 Haziran 2024 ile 1 Haziran 2025 arasında yayımlanan 39.080 CVE kaydına dayanıyor.

CISA ile FBI, Mart 2024'teki Secure by Design uyarısında, açık sınıfı yirmi yıldır bilindiği ve etkili önlemleri olduğu hâlde üreticilerin bu kusuru taşıyan ürünler geliştirmeyi sürdürdüğünü vurguluyor. Uyarı, üreticilerin kodlarını resmî bir incelemeden geçirmesini, müşterilerin de tedarikçilerine bu incelemeyi sormasını istiyor.

Gerçek bir örnek: MOVEit Transfer

CISA ile FBI'ın 7 Haziran 2023 tarihli ortak danışma notuna (AA23-158A) göre fidye yazılımı grubu CL0P (TA505), 27 Mayıs 2023'ten itibaren Progress Software'in dosya aktarım ürünü MOVEit Transfer'daki, o güne kadar bilinmeyen bir SQL injection açığını (CVE-2023-34362) istismar etmeye başladı. İnternete açık MOVEit uygulamalarına LEMURLOOT adlı bir web shell yerleştirildi ve alttaki veritabanlarından veri çalındı.

NVD kaydına göre açık, kimliği doğrulanmamış bir saldırganın veritabanına erişmesine imkân veriyordu; CVSS 3.1 puanı 9,8 (kritik).

SQL injection nasıl önlenir?

OWASP'ın SQL Injection Prevention Cheat Sheet'i dört birincil savunma sayıyor; dördüncüsü, yani girdiyi kaçış karakterleriyle temizlemek "kesinlikle önerilmiyor". CISA ve FBI'a göre de girdi temizleme kırılgandır ve sıklıkla aşılır. Öteki üç savunma ve en az yetki şunlar:

  1. Parametreli sorgu (prepared statement): Sorgunun yapısı önceden yazılır, kullanıcı değeri ayrı bir parametre olarak gider. OWASP'a göre veritabanı böylece kodu veriden her durumda ayırır; CISA ve FBI bunun bütün uygulamalarda zorunlu tutulmasını istiyor.
  2. Doğru kurulmuş saklı yordam (stored procedure): Güvenli yazılırsa aynı işi görür. OWASP Top 10:2025'e göre ise sorgu ile veriyi birleştiren bir saklı yordam, parametreli olsa bile açık verebilir.
  3. İzin listesiyle doğrulama: Tablo, sütun adı ve sıralama yönü parametreye bağlanamaz; OWASP bu değerlerin önceden belirlenmiş geçerli adlara eşlenmesini öneriyor ve izin listesini her durumda ikinci savunma sayıyor.
  4. En az yetki: Uygulama hesabına DBA yetkisi verilmez; yalnız okuması gereken hesap sadece ihtiyaç duyduğu tablolarda okuma yetkisi alır ve her uygulama ayrı bir veritabanı hesabıyla bağlanır (IAM yazımız).

Python'un sqlite3 modülünde yer tutucuyla (placeholder) yazılan bir sorgu şöyle görünür:

import sqlite3

baglanti = sqlite3.connect("ornek.db")
musteri_id = 1042  # formdan ya da API'den gelen değer

satirlar = baglanti.execute(
    "SELECT id, tarih, tutar FROM siparis WHERE musteri_id = ?",
    (musteri_id,),  # değer sorguya ayrı parametre olarak gider
).fetchall()

ORM riski azaltır ama sıfırlamaz: OWASP'a göre girdi sorguya eklenirse ORM'de de yetkisiz veri erişimi doğar. Django'nun belgesine göre queryset'ler sorguyu parametreyle kurar; ham SQL ise az ve dikkatle kullanılmalı.

Tespit: kod incelemesi, test, WAF ve log

OWASP, injection'ı bulmak için kaynak kod incelemesini otomatik testle (fuzzing dahil) birleştirmeyi öneriyor. Testler parametreleri, başlıkları, adresi, çerezleri ve API'lerin taşıdığı JSON ile XML girdilerini kapsamalı. SAST, DAST ve IAST araçlarını CI/CD pipeline'ına eklemek de açığı canlıya çıkmadan yakalamaya yardım eder. SAST kaynak kodu inceleyip SQL injection'ı satırıyla gösterir ama çok yanlış alarm üretir; DAST uygulamayı genellikle dışarıdan tarar. NIST'in tanımıyla sızma testi ise gerçek saldırıları taklit ederek güvenlik önlemlerini aşmanın yollarını arar (sızma testi yazımız); düzenli taramayı zafiyet taraması hizmetimizde ele alıyoruz.

  • WAF: Web uygulama güvenlik duvarı bilinen saldırı desenlerini durdurabilir; CWE-89 ise etkinliğini orta sayıyor, çünkü bütün girdi yollarını kapsamayabilir ve bozuk biçimli girdiyle aşılabilir. Ayrıntısı WAF yazımızda, işletimi uygulama güvenliği (WAF) hizmetimizde.
  • Log ve SIEM: OWASP, girdi doğrulama ve söz dizimi hatalarının kaydedilip SIEM gibi merkezi bir sisteme gönderilmesini, ciddi olaylarda ekibe hemen uyarı gitmesini istiyor (SIEM ve SOC yazımız).

Açık bulunduğunda ne yapılmalı?

  1. Hazır bir üründeyse güncelleyin: CISA'nın istismar edildiği bilinen açıklar kataloğu (KEV), MOVEit için üreticinin talimatıyla güncellemeyi istedi (NVD kaydı). Süreci yama yönetimi yazımızda, işletimini yama ve güvenlik açığı yönetimi hizmetimizde anlatıyoruz.
  2. Kendi kodunuzdaysa sorguyu parametreli hâle getirin ve aynı kalıbı bütün kodda arayın: CISA ve FBI tek bir açığın değil, açık sınıfının ortadan kaldırılmasını istiyor. Bu sırada WAF'taki sanal yama (virtual patching) zaman kazandırır; OWASP'a göre bilinen istismar yolunu kapatır ama açığı kaldırmaz.
  3. İzleri inceleyin: CISA'nın MOVEit notu, olağandışı etkinliğin bir ağ izleme aracıyla incelenmesini, sunucularda ve Active Directory'de yeni ya da tanınmayan hesapların aranmasını öneriyor.
  4. Etkiyi değerlendirin: Sızan kayıtlar kişisel veri içeriyorsa hukuki bildirim yükümlülükleri doğabilir (veri ihlali bildirimi yazımız).

Sık sorulan sorular

SQL injection ne demek? SQL enjeksiyonu demek; kısaltması SQLi. Kullanıcı girdisinin SQL sorgusuna karışıp sorgunun anlamını değiştirdiği güvenlik açığıdır.

SQL injection saldırısı nasıl gerçekleşir? Uygulama sorguyu kullanıcının değeriyle birleştirerek kurar, veritabanı da söz dizimi geçerli her sorguyu çalıştırır. Saldırgan girdisini bu söz dizimine uydurup sorgunun işini değiştirir.

SQL injection nasıl önlenir? Temel önlem parametreli sorgudur; güvenli yazılmış saklı yordam, izin listesiyle doğrulama ve en az yetki onu tamamlar.

WAF SQL injection'ı engeller mi? Bilinen desenleri engelleyebilir ama bütün girdi yollarını kapsamayabilir. Açığı kaldıran, kodun düzeltilmesidir.

ORM kullanmak SQL injection'ı önler mi? Riski azaltır, çünkü Django gibi ORM'ler sorguyu parametreyle kurar. Ham SQL yazılan ya da girdinin sorguya eklendiği yerlerde açık yine oluşabilir.

Kaynaklar