SQL injection (SQLi), OWASP Top 10''un 25 yıldır listede olan klasiğidir. Veritabanına giden sorguya kullanıcı input''u eklediğinizde — ve bunu parametreli sorgu yerine string concatenation ile yaparsanız — saldırgan sorgu mantığınızı değiştirebilir: tablo dökmek, kullanıcı oluşturmak, hatta OS komutu çalıştırmak. Bu yazı SQLi''nin nasıl çalıştığını ve nasıl kalıcı olarak önleneceğini pratik örneklerle açıklar.

Klasik SQL Injection

İlgili rehberler: SSL sertifikası nasıl alınır · OWASP Top 10 2026 · JWT güvenlik · Parola hash (BCrypt, Argon2) · DDoS koruma

// Açık kod
const email = req.body.email;  // Kullanıcı input''u
const sql = `SELECT * FROM users WHERE email = '${email}' AND password = '${req.body.password}'`;
db.query(sql);

// Saldırgan şu email''i girer:
// admin@x.com' --
// Sorgu şuna dönüşür:
// SELECT * FROM users WHERE email = 'admin@x.com' --' AND password = '...'
// -- sonrası SQL''de yorum. Parola kontrolü by-pass!

Blind SQL Injection

Uygulama sorgu çıktısını göstermese bile saldırgan sorgunun true/false davranışından veri çıkarabilir. Örneğin giriş formunun "yanlış parola" vs "kullanıcı yok" cevaplarını ayıran saldırgan karakter karakter parola hash''i tahmin eder.

-- Boolean-based blind SQLi
admin@x.com' AND SUBSTRING(password,1,1)='a' --
-- Yanıt: "Yanlış parola" → ilk karakter 'a' değil
-- 'b', 'c', ... deneyerek 30 isteğe 1 karakter öğrenir

-- Time-based blind SQLi
admin@x.com' AND IF(SUBSTRING(password,1,1)='a', SLEEP(5), 0) --
-- Cevap 5 saniye gecikiyorsa ilk karakter 'a'

Union-Based

-- Orijinal sorgu: SELECT name, email FROM users WHERE id = ?
-- Saldırgan id olarak:
1 UNION SELECT username, password FROM admins --
-- Sorgu: SELECT name, email FROM users WHERE id = 1
--         UNION SELECT username, password FROM admins --
-- Çıktı: admin tablosu sızar

Tek Çözüm: Parameterized Queries

Escape fonksiyonları, blacklist filtreleri, karakter değişimleri — hepsi bypass edilebilir. Tek güvenli yöntem: sorgu yapısı ile veri''yi tamamen ayıran prepared statement / parameterized query. Veri asla SQL olarak yorumlanmaz.

// Node.js + pg
await pool.query(
    'SELECT * FROM users WHERE email = $1 AND password_hash = $2',
    [email, passwordHash]
);

// Node.js + mysql2
await db.execute(
    'SELECT * FROM users WHERE email = ? AND password_hash = ?',
    [email, passwordHash]
);
# Python + psycopg
cur.execute(
    'SELECT * FROM users WHERE email = %s AND password_hash = %s',
    (email, password_hash)
)

# Python + SQLAlchemy (ORM)
User.query.filter_by(email=email).first()
// PHP + PDO
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();

ORM Kullanıyorsanız...

Sequelize, Prisma, TypeORM, SQLAlchemy, Django ORM otomatik parametrize eder. Ancak raw(), literal(), query() gibi ham SQL metotlarında dikkat — parametre geçmeyi unutursanız açıksınız.

// Prisma — güvenli
await prisma.user.findMany({ where: { email } });

// Prisma raw — YANLIŞ
await prisma.$queryRawUnsafe(`SELECT * FROM users WHERE email = '${email}'`);

// Prisma raw — DOĞRU
await prisma.$queryRaw`SELECT * FROM users WHERE email = ${email}`;
// Template literal tag otomatik parametrize eder

Savunma Katmanları

  • Parameterized queries — birincil savunma
  • Least privilege — uygulama DB kullanıcısı sadece gerekli tablolara erişsin, DROP/ALTER yetkisi olmasın
  • Input validation — tip ve uzunluk kontrolü (örn: id sadece sayı)
  • WAF — Cloudflare, ModSecurity saldırı paternlerini yakalar
  • Error handling — DB hata mesajını kullanıcıya gösterme, log''la
Uyarı
stored procedure kullanmak tek başına yetmez. Prosedür içinde de string concatenation yapılabilir. Yine parametreli çağrı şart.

Test Etme

# sqlmap ile hızlı test (sadece kendi sisteminde)
sqlmap -u 'https://example.com/api/user?id=1' --batch --level=3

# OWASP ZAP otomatik scan
# Burp Suite manuel test
# GitHub Actions içinde semgrep ile SAST
semgrep --config=p/sql-injection .

Web Güvenliği ve Uygulama Savunması

Modern web güvenliği katmanlı savunma (defense-in-depth) ile yapılır: TLS 1.3 ve HSTS ile şifreli iletişim, WAF (Web Application Firewall) ile OWASP Top 10 saldırılarına karşı koruma, BCrypt veya Argon2id ile parola hash'leme, JWT token'larında imza doğrulama (HMAC veya RSA), CSRF token + SameSite cookie ile cross-site istek koruması ve Content Security Policy ile XSS azaltma. SQL injection önleme için prepared statement, brute force için fail2ban veya rate limiting, DDoS koruması için Cloudflare/Anti-DDoS sağlayıcı zorunludur. Güvenlik açığı taraması (Burp Suite, OWASP ZAP) ve düzenli güvenlik denetimi; üretim ortamında veri sızıntısı ve hesap ele geçirme risklerini büyük ölçüde azaltır.

SQL injection güvenlik denetimi

Kod tabanınızın SQLi taraması, pentest raporu ve eğitim için iletişime geçin

WhatsApp