Genel Bakış
SQL Injection (SQLi), bir saldırganın kullanıcı girdi alanlarına ya da parametrelere kötü amaçlı SQL ifadeleri ekleyerek bu girdilerin arka uç SQL veritabanı tarafından yürütülmesini sağladığı bir kod enjeksiyon tekniğidir. Bir uygulama, kullanıcı tarafından sağlanan veriyi yeterli doğrulama ya da kaçış karakteri işlemi uygulamadan SQL sorgusuna dahil ettiğinde, saldırgan sorgunun söz dizimini ve anlambilimini değiştirebilir; kimlik doğrulamasını atlatabilir, hassas verileri çekebilir, kayıtları değiştirebilir veya silebilir ve bazı yapılandırmalarda işletim sistemi komutları çalıştırabilir.
SQL Injection, yirmi yılı aşkın süredir en kritik web uygulaması güvenlik açıkları arasında yer almakta ve OWASP'ın Injection kategorisinde (A03:2021) lider konumunu korumaktadır. MITRE tarafından CWE-89 olarak sınıflandırılmaktadır.
Nasıl Çalışır?
Temel neden, kullanıcı girdisinin çalıştırılabilir kod yerine veri olarak işlenmemesidir. Bir web uygulaması string birleştirme yoluyla SQL sorgusu oluşturduğunda, saldırgan tek tırnak, çift tire, noktalı virgül gibi SQL meta karakterleri içeren girdiler vererek sorgunun söz dizimini ve semantiğini değiştirebilir.
Klasik örnek (kimlik doğrulama atlatma):
-- Hedeflenen sorgu:
SELECT * FROM users WHERE username = 'alice' AND password = 'secret';
-- Saldırgan kullanıcı adı olarak şunu girer: ' OR '1'='1' --
-- Oluşan sorgu:
SELECT * FROM users WHERE username = '' OR '1'='1' --' AND password = '...';
-- Geri kalanı yorum satırına alınır; koşul her zaman doğrudur.
SQL Injection çeşitli biçimlerde ortaya çıkar:
- Bant İçi SQLi (Klasik): Veriler, zararlı yükün iletildiği aynı kanal üzerinden elde edilir. Hata tabanlı (veritabanı hata mesajlarından bilgi elde etme) ve union tabanlı (başka tablolardan veri almak için UNION SELECT ekleme) olmak üzere ikiye ayrılır.
- Kör SQLi (Blind SQLi): Uygulama sorgu sonuçlarını veya hata mesajlarını doğrudan döndürmez. Saldırganlar bilgiyi uygulama davranışından çıkarır. Boolean tabanlı kör SQLi, doğru/yanlış koşullar kullanarak veriyi bit bit sızdırır; zaman tabanlı kör SQLi ise sonuçları çıkarsamak için koşullu zaman gecikmelerini (
SLEEP()veyaWAITFOR DELAY) kullanır. - Bant Dışı SQLi: Veriler, veritabanı işlevleri tarafından tetiklenen DNS veya HTTP istekleri gibi ayrı bir kanal üzerinden sızdırılır (örn. MSSQL'de
xp_cmdshell, Oracle'daUTL_HTTP). Belirli veritabanı özelliklerine ve ağ çıkış izinlerine ihtiyaç duyar. - İkinci Dereceli (Depolanmış) SQLi: Kötü amaçlı girdi veritabanında saklanır ve daha sonra yeniden doğrulama yapılmadan bir SQL sorgusunda kullanılmak üzere geri alınır; bu da ertelenmiş bir enjeksiyon noktası oluşturur.
Veritabanı hesabının yükseltilmiş ayrıcalıklara sahip olması durumunda önem derecesi daha da artar: saldırganlar rastgele dosyalar okuyabilir (MySQL'de LOAD_FILE()), dosya sistemine dosya yazabilir (INTO OUTFILE) veya işletim sistemi komutları çalıştırabilir (MSSQL'de xp_cmdshell), bu da tam sunucu ele geçirilmesiyle sonuçlanabilir.
İş Etkisi
Başarılı bir SQL Injection saldırısı çok boyutlu ve ağır sonuçlar doğurabilir:
- Veri ihlali: Kişisel tanımlayıcı bilgiler (KTB), kimlik bilgileri, ödeme kartı verileri, sağlık kayıtları ve tescilli iş verilerinin sızdırılması — GDPR, HIPAA, PCI DSS ve benzeri düzenlemeler kapsamında ihlal bildirimi yükümlülüğü doğurur.
- Kimlik doğrulama atlatma: Saldırganlar, parola bilmeksizin yöneticiler dahil herhangi bir kullanıcı olarak oturum açabilir.
- Veri bütünlüğü kaybı: Kayıtlar değiştirilebilir veya silinerek uygulama durumu ve iş süreçleri bozulabilir.
- Hizmet kesintisi: Tabloların silinmesi veya veritabanı şemasının bozulması uygulama kesintisine yol açar.
- Tam sunucu ele geçirilmesi: Yanlış yapılandırılmış veritabanlarında işletim sistemi düzeyinde komut yürütme, tüm altyapının ele geçirilmesine, yanal harekete ve fidye yazılımı konuşlandırılmasına neden olabilir.
- Yasal ve mali cezalar: GDPR kapsamındaki para cezaları 20 milyon Euro'ya veya yıllık küresel cirosunun %4'üne kadar ulaşabilir; PCI DSS ihlalleri kart kuruluşu cezalarına ve ödeme işleme haklarının kaybına yol açabilir.
- İtibar zararı: Bir ihlalın kamuoyuna duyurulması müşteri güvenini zedeler ve kalıcı gelir kayıplarına neden olabilir.
Nasıl Düzeltilir?
- Parametreli sorgular (hazırlanmış ifadeler) kullanın: Bu, birincil ve en etkili savunmadır. SQL kodunu veriden API düzeyinde ayırarak kullanıcı girdisinin hiçbir zaman SQL söz dizimi olarak yorumlanmamasını sağlayın. Tüm büyük veritabanı sürücüleri ve ORM'ler bu kalıbı destekler.
-- Güvensiz (string birleştirme): query = "SELECT * FROM users WHERE username = '" + username + "'"; -- Güvenli (parametreli): query = "SELECT * FROM users WHERE username = ?"; preparedStatement.setString(1, username); - İyi bakımlı bir ORM veya sorgu oluşturucu kullanın: Hibernate, SQLAlchemy, ActiveRecord ve Entity Framework gibi çerçeveler dahili olarak parametreli sorgular kullanır. String birleştirmeyle ORM içinde bile ham sorgu oluşturmaktan kaçının (örn.
raw()veyaexecute()ile string interpolasyonunu kullanmayın). - Katı girdi doğrulaması uygulayın: Tüm kullanıcı girdilerini beklenen tür, format, uzunluk ve aralığa göre izin verilenler listesiyle doğrulayın. Uyumsuz girdileri reddedin. Bu, derinlemesine savunma önlemidir; parametreli sorguların yerini alamaz.
- En az ayrıcalık ilkesini uygulayan veritabanı hesapları kullanın: Uygulama veritabanı hesapları yalnızca işlevleri için gereken izinlere sahip olmalıdır (belirli tablolarda SELECT, INSERT, UPDATE). Uygulama sorguları için DBA veya root hesabını asla kullanmayın. Kesinlikle gerekmiyorsa FILE ve EXECUTE ayrıcalıklarını reddein.
- Son çare olarak kullanıcı girdisini kaçış karakteriyle işleyin: Parametreli sorgular kullanılamıyorsa (örn. dinamik tablo veya sütun adları), veritabanı sürücüsünün yerel kaçış işlevini kullanın; ancak bu yaklaşım hataya açıktır ve mümkün olduğunda kaçınılmalıdır.
- Web Uygulama Güvenlik Duvarı (WAF) etkinleştirin: Bir WAF, iletim sırasında bilinen SQLi kalıplarını tespit edip engelleyebilir. Bu, güvenli kodlama pratiklerinin yerini alamayacak tamamlayıcı bir kontroldür; WAF'lar atlatılabilir.
- Ayrıntılı hata mesajlarını gizleyin: Uygulamayı son kullanıcılara genel hata sayfaları döndürecek şekilde yapılandırın. HTTP yanıtlarında ham SQL hata mesajları, yığın izleri veya sorgu ayrıntılarını asla açığa çıkarmayın.
- Düzenli güvenlik testleri yapın: SDLC sürecinde SAST (statik analiz), DAST (dinamik analiz) ve manuel sızma testlerine SQL Injection testlerini dahil edin. Sensagraph, sürekli tarama yoluyla SQL Injection güvenlik açıklarını otomatik olarak tespit eder.
- Veritabanı yazılımını güncel tutun: SQLi etkisini artırabilecek bilinen veritabanı motoru açıklarına maruziyeti azaltmak için satıcı güvenlik yamalarını derhal uygulayın.
Kaynaklar
- OWASP Top 10 2021 – A03: Injection
- OWASP – SQL Injection Saldırısı
- OWASP SQL Injection Önleme Hızlı Başvuru Kılavuzu
- OWASP Sorgu Parametreleme Hızlı Başvuru Kılavuzu
- MITRE CWE-89: SQL Komutunda Kullanılan Özel Öğelerin Yetersiz Nötrleştirilmesi
- PortSwigger Web Security Academy – SQL Injection
- NIST – SQL Injection Genel Bakış