Mobil Geliştirmede SQL Injection: Nedir, Saldırı Yöntemleri ve Korunma

Yazar: IT Sectr Yayınlanma: 2026-04-06 Okuma süresi: 9 dk

SQL Injection, bir saldırganın sorgu parametrelerine kötü amaçlı SQL kodu enjekte ederek verilere yetkisiz erişim veya bunları değiştirme yeteneği elde ettiği bir veritabanı saldırı türüdür. OWASP (2025)'e göre SQL Injection, veritabanının tamamen tehlikeye girmesine yol açabilen kritik güvenlik açıklarından biri olmaya devam etmektedir. SQL kodu enjeksiyonu, saldırganın kayıtları okumasına, değiştirmesine ve silmesine ve bazı durumlarda sunucunun işletim sistemine erişmesine olanak tanır.

Önemli Noktalar

  • SQL Injection — kullanıcı parametreleri aracılığıyla SQL kodu enjekte ederek veritabanı sorgu mantığını değiştirme
  • Sorgu Parametreleştirmesi — ana koruma yöntemi: prepared statements kullanarak SQL kodunu verilerden ayırma
  • Saldırı Türleri — klasik enjeksiyon (WHERE aracılığıyla), Blind SQLi (mantıksal çıkarımlar), UNION-based (diğer tabloları okuma)
  • Error-based SQLi — veritabanı hata mesajları aracılığıyla veri çıkarma
  • ORM Çerçeveleri — doğru kullanıldığında SQLi riskini azaltır, ancak tamamen ortadan kaldırmaz

SQL Injection Nedir?

SQL Injection, bir uygulamanın kullanıcı verileriyle dize birleştirmesi yaparak SQL sorguları oluşturduğunda ortaya çıkan bir güvenlik açığıdır. Bir saldırgan, SQL komutunun yapısını değiştiren özel olarak hazırlanmış bir dizeyi sorgu parametresine iletir. Enjekte edilen dize, veri olmak yerine SQL kodunun bir parçası haline gelir ve saldırganın veritabanına karşı keyfi sorgular yürütmesine olanak tanır. Verizon Veri İhlali Raporu (2025)'e göre SQL Injection, araştırılan tüm veri ihlallerinin %8'inde mevcuttur.

SQL Injection Neden Hala Geçerli?

Bilinen bir güvenlik açığı olmasına rağmen (ilk olarak 1990'ların sonunda bahsedilmiştir), SQL Injection modern uygulamalarda hala bulunmaktadır. Bunun nedeni insan hatasıdır: geliştiriciler dize birleştirmeli kod yazar, eski kod yeniden düzenlenmez ve ORM çerçeveleri yanlış kullanılır (örneğin, dize enterpolasyonlu ham sorgular). Veracode (2026)'ya göre taranan tüm uygulamaların yaklaşık %14'ü en az bir SQLi güvenlik açığı içermektedir.

Bir Saldırgan Ne Yapabilir?

Başarılı bir SQL Injection, saldırgana geniş bir yetenek yelpazesi sağlar: parola karmaları ve kullanıcıların kişisel verileri dahil olmak üzere herhangi bir veritabanı tablosunu okumak; kayıtları değiştirmek ve silmek; yönetim işlemlerini yürütmek (DROP TABLE, TRUNCATE); ve bazı yapılandırmalarda xp_cmdshell (MSSQL) veya INTO OUTFILE (MySQL) aracılığıyla uzaktan komut yürütme. Sonuçlar, kullanıcı verilerinin sızmasından sistem kontrolünün tamamen kaybedilmesine kadar uzanır.

SQL Enjeksiyon Türleri

SQL enjeksiyonları, veritabanından veri çıkarma yöntemine göre sınıflandırılır. Yöntemin seçimi, uygulamanın sorgu sonuçlarını ve hata mesajlarını nasıl işlediğine bağlıdır. OWASP sınıflandırması üç ana türü tanımlar: In-band (aynı kanal aracılığıyla veri çıkarma), Inferential/Blind (mantıksal çıkarımlar) ve Out-of-band (başka bir kanal aracılığıyla veri iletimi).

TürVeri Çıkarma YöntemiKarmaşıklıkSıklık
In-band (klasik)Doğrudan sorgu sonucu aracılığıylaDüşükYüksek
Blind SQLiSunucu yanıtlarından mantıksal çıkarımlarYüksekOrta
Out-of-bandHarici kanal (DNS, HTTP) aracılığıylaOrtaDüşük

In-band SQL Injection (Klasik)

En yaygın tür. Bir saldırgan, sorgu parametresine SQL kodu enjekte eder ve enjeksiyonun sonucu doğrudan sunucu yanıtında görünür. İki alt tür: Error-based (DB hata mesajları aracılığıyla) ve UNION-based (UNION SELECT operatörü aracılığıyla). Error-based, tablo adını veya sorgu yapısını ortaya çıkarabilecek MySQL sözdizimi hatası gibi hata mesajlarındaki bilgileri kullanır. UNION-based, meşru sorgu sonuçlarını veritabanındaki diğer tablolardaki verilerle birleştirmeye olanak tanır.

Blind SQL Injection (Kör)

Uygulamanın sorgu sonuçlarını veya hata mesajlarını göstermediği durumlarda kullanılır. Bir saldırgan, mantıksal koşullar içeren sorgular göndererek ve sunucu yanıtlarındaki farklılıkları (örneğin, yanıt süresi veya sayfa içeriği) analiz ederek evet/hayır soruları sorar. Time-based Blind SQLi, koşulları onaylamak için gecikme işlevlerini (SLEEP, WAITFOR DELAY) kullanır — sayfanın yüklenmesi daha uzun sürerse koşul doğrudur. Bu yöntem çok yavaştır — tek bir kaydı çıkarmak saatler alabilir.

python
# Blind SQL Injection Örneği (zaman tabanlı)
# SQLi savunmasızsa, koşul karşılandığında SLEEP(2) yürütülür
import requests
import time

payload = "' OR IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a',SLEEP(2),0) -- "
url = "http://example.com/user?id=1" + payload

start = time.time()
response = requests.get(url)
elapsed = time.time() - start

# Yanıt >2 saniye sonra gelirse — parolanın ilk harfi 'a'
print(f"Time: {elapsed:.2f}s - First letter is 'a'" if elapsed > 2 else "First letter is not 'a'")

Out-of-band SQL Injection

Veriler HTTP yanıtı aracılığıyla değil, alternatif kanallar (DNS sorguları, harici bir sunucuya HTTP istekleri, SMTP) aracılığıyla iletilir. Uygulamanın sorgu sonuçlarını döndürmediği veya hata göstermediği durumlarda kullanılır. MySQL, DNS sorgusu başlatabilen LOAD_FILE() işlevini destekler ve MSSQL, uzak bir SMB sunucusuna veri göndermek için xp_dirtree'ye sahiptir. Out-of-band SQL Injection etkilidir ancak ek saldırgan sunucu kurulumu ve belirli DB işlevleri gerektirir.

SQL Enjeksiyonu Nasıl Çalışır?

SQL Injection mekanizması, SQL'in dize değişmezleri için tırnak işaretleri kullanmasına dayanır. Bir uygulama, kullanıcı girişini kaçış karakterleri olmadan doğrudan bir SQL sorgusuna eklerse, saldırgan dizeyi “kapatabilir” ve isteğe bağlı SQL kodu ekleyebilir. Örneğin, SELECT * FROM users WHERE name = '$input' sorgusuna ' OR '1'='1 eklenmesi, onu SELECT * FROM users WHERE name = '' OR '1'='1' haline getirir ve tüm kullanıcıları döndürür.

Klasik Örnek: Kimlik Doğrulama Atlaması

SELECT * FROM users WHERE username = '$user' AND password = '$pass' sorgusunu kullanan bir giriş formu düşünün. Bir saldırgan, kullanıcı adı alanına admin' -- girer ve parolayı boş bırakırsa, sonuçtaki sorgu SELECT * FROM users WHERE username = 'admin' -- ' AND password = '' olur. -- karakterleri sorgunun geri kalanını yorum haline getirerek parola kontrolünü devre dışı bırakır. Sunucu, admin kullanıcı kaydını döndürür ve saldırgan parolayı bilmeden giriş yapar.

python
# SQL Injection Örneği — Kimlik Doğrulama Atlaması
# SAVUNMASIZ KOD: doğrudan dize birleştirmesi
def login_vulnerable(username, password):
    query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
    cursor.execute(query)
    return cursor.fetchone() is not None

# username = "admin' --" parola kontrolünü geçersiz kılar
# GÜVENLİ SÜRÜM: parametreleştirilmiş sorgu
def login_secure(username, password):
    query = "SELECT * FROM users WHERE username = %s AND password = %s"
    cursor.execute(query, (username, password))
    return cursor.fetchone() is not None

UNION-based: Diğer Tabloları Okuma

UNION SELECT operatörü, iki SELECT sorgusunun sonuçlarını birleştirmeye olanak tanır. Bir saldırgan savunmasız bir parametre bulursa, başka bir tablodan sorgu ile UNION SELECT ekler. Örnek: ' UNION SELECT username, password FROM admins --. Başarı koşulu, her iki sorgudaki sütun sayısının eşleşmesidir. Sütun sayısı ORDER BY aracılığıyla belirlenir (' ORDER BY 1--, ardından 2, 3... hata oluşana kadar). Sütun sayısını bilen saldırgan, aynı sayıda alanla UNION SELECT ekler.

Mobil Uygulamalarda SQL Injection

Mobil uygulamalar, hem sunucu tarafında (API) hem de istemci tarafında — yerel veritabanlarında (SQLite, Realm) — SQL Injection ile karşı karşıyadır. Mobil API'lerdeki sunucu tarafı SQLi, web uygulamalarına benzerken, yerel veritabanları ek bir vektör oluşturur. Bir uygulama SQLite'da veri depoluyor ve dize birleştirme ile sorgular yürütüyorsa, API aracılığıyla yerel veritabanına giren kötü amaçlı veriler, sonraki işleme sırasında SQLi'yi tetikleyebilir.

Android/iOS'te SQLite'da SQL Injection

Cihazdaki yerel SQLite veritabanı da, uygulama dizeleri birleştirerek sorgular oluşturuyorsa SQL Injection'a karşı savunmasızdır. Android'deki Content Providers ve iOS'teki Core Data varsayılan olarak parametreleştirme kullanır, ancak ham sorgular geliştiricinin dikkatini gerektirir. SQLite, noktalı virgülle ayrılmış birden çok sorguyu desteklemez, bu da saldırganın seçeneklerini sınırlar ancak WHERE koşulları aracılığıyla veri okumaya karşı koruma sağlamaz. Android'de her zaman selectionArgs ve iOS'te parametrelerle NSPredicate kullanın.

Mobil Uygulama API'si Aracılığıyla SQL Injection

Bir mobil uygulamanın iletişim kurduğu API, herhangi bir web sunucusu gibi savunmasızdır. Mobil geliştiriciler genellikle SQLi'nin yalnızca bir backend sorunu olduğunu varsayar, ancak güvenlik açığı, istemciden parametreleri kabul eden API uç noktasında oluşur. Sorumlulukların ayrılması koruma sağlamaz: backend geliştiricisi sorguyu parametreleştirmeyi unuttuysa, kullanıcının mobil uygulaması bir saldırı vektörü haline gelir. Backend'in ORM veya prepared statements kullanmasını talep edin.

kotlin
// Android'de Yerel SQLite'da SQL Injection Örneği
// SAVUNMASIZ KOD: doğrudan birleştirme
fun getUserVulnerable(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = $userId", null
    )
}

// GÜVENLİ SÜRÜM: selectionArgs aracılığıyla parametreleştirme
fun getUserSecure(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = ?",
        arrayOf(userId)
    )
}

SQL Injection Önleme Yöntemleri

SQL Injection'a karşı koruma basit bir ilkeye dayanır: SQL sorgularında kullanıcı girişine asla güvenmeyin. Güvenilir tek yöntem, SQL kodu ve verilerin ayrı ayrı iletildiği sorgu parametreleştirmesidir (prepared statements). Diğer tüm yöntemler — kaçış, doğrulama, WAF — ek güvenlik katmanlarıdır ancak parametreleştirmenin yerini tutmaz. OWASP (2025)'e göre parametreleştirme, SQL Injection saldırılarının %100'ünü önler.

Prepared Statements (Parametreleştirilmiş Sorgular)

Prepared statements kullanılırken, SQL sorgusu önce DB sunucusu tarafından veri olmadan derlenir ve ardından parametre değerleri ayrı ayrı iletilir. Veritabanı, parametreleri yürütülebilir kod olarak değil, veri olarak ele alır. Bir saldırgan ' OR '1'='1 iletse bile, veritabanı bunu SQL kodu olarak değil, bir dize değeri olarak yorumlar. Prepared statements, PHP'de PDO, Java'da PreparedStatement, Python'da cursor.execute gibi tüm modern diller ve çerçeveler tarafından desteklenir.

ORM Çerçeveleri ve Sorgu Oluşturucular

Modern ORM'ler (Hibernate, Entity Framework, SQLAlchemy, Room), geliştirici ham sorgulara geçmediği sürece sorguları yürütürken otomatik olarak parametreleştirme kullanır. Ancak, ORM'ler tamamen koruma sağlamaz: JPA'daki @Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true) gibi yapılar, parametrelerin birleştirme yoluyla değil, adlandırılmış parametreler aracılığıyla iletilmesini gerektirir. Sorgu oluşturucular (Knex, jOOQ) da ham yöntemler kullanılmadığında varsayılan olarak sorguları parametreleştirir.

Dize Kaçışı (birincil yöntem olarak önerilmez)

Özel karakterlerin kaçışı (mysql_real_escape_string), tüm SQL Injection türlerine karşı koruma sağlamayan eski bir yöntemdir. Sorun: kaçış, kodlamaya bağlıdır ve çok baytlı kodlamalar (örneğin, Asya sistemlerinde GBK) kullanılırken atlatılabilir. Kaçışı yalnızca parametreleştirmenin mümkün olmadığı eski kodlarda ve her zaman sıkı giriş türü doğrulamasıyla birlikte kullanın.

YöntemEtkinlikÖneri
Prepared Statements100%Tüm sorgular için zorunlu
ORM (doğru kullanım)99%Önerilir
Dize Kaçışı70% (kodlamaya bağlı)Yalnızca eski
Giriş Doğrulaması (beyaz liste)50% (yalnızca sayılar)Ek
WAF (Web Application Firewall)60%Ek

Veritabanı için En Az Ayrıcalık İlkesi

Uygulama hesabı, minimum gerekli ayrıcalıklara sahip olmalıdır: SELECT, INSERT, UPDATE, DELETE — yalnızca uygulamanın gerçekten ihtiyaç duyduğu tablolarda. Uygulama hesabı için DROP, TRUNCATE, CREATE kullanımını yasaklayın. Bu, başarılı bir SQL Injection durumunda bile hasarı sınırlar: saldırgan tabloları silemez veya yönetim işlemlerini yürütemez.

SQL Enjeksiyonlarını Tespit Etme Araçları

Düzenli SQL Injection testi, güvenli geliştirme hattının bir parçası olmalıdır. Statik analiz, dinamik tarama ve manuel sızma testinin bir kombinasyonu en iyi sonuçları verir. Synopsys Siber Güvenlik Raporu (2025)'e göre, otomatik tarayıcılar SQLi güvenlik açıklarının %70'ine kadarını bulur, ancak karmaşık Kör saldırılar manuel test gerektirir.

  • sqlmap — SQL Injection'ın otomatik tespiti ve kullanımı için en popüler araç
  • OWASP ZAP — aktif SQLi tarama modülleriyle ücretsiz bir DAST tarayıcı
  • Burp Suite Scanner — otomatik SQL Injection tespitiyle profesyonel bir araç
  • SonarQube — SQLi kalıpları dahil güvenlik açıkları için statik kod analizi
  • CodeQL — kaynak kodunda SQL enjeksiyonlarını bulmak için anlamsal kod analizi

Mobil uygulamalar için yerel SQLite analizi de önemlidir: tüm rawQuery çağrılarını, ContentProvider sorgularını ve rawQuery ile Room sorgularını kontrol edin. Araçlar: Android Studio Lint (SQLite'da SQLi'yi tespit eder), APK/IPA'nın otomatik statik ve dinamik analizi için MobSF (Mobile Security Framework). Ayrıca mobil uygulama trafiğinin proxy müdahalesiyle sqlmap aracılığıyla API uç noktalarını test etmeniz önerilir.

Sıkça Sorulan Sorular

SQL Injection ve NoSQL Injection arasındaki fark nedir?

SQL Injection, SQL sorguları aracılığıyla ilişkisel veritabanlarına saldırır. NoSQL Injection, sorgu operatörleri ($gte, $ne, $where) aracılığıyla ilişkisel olmayan veritabanlarını (MongoDB, Couchbase) etkiler. MongoDB'de, uygulama bir JSON dizesinden BSON belgesi oluşturuyorsa enjeksiyon mümkündür. Koruma mekanizmaları benzerdir: parametreleştirme ve tür doğrulaması.

Kodda SQL Injection'ı kendi başınıza nasıl tespit edersiniz?

SQL sorgularının kullanıcı verileriyle dize birleştirmesi yoluyla oluşturulduğu tüm yerleri bulun. "SELECT ... WHERE id = " + userId veya f"UPDATE ... SET name = '{name}'" gibi kalıplar arayın. Bu tür her satır potansiyel bir SQL enjeksiyonudur. Tümünü parametreleştirilmiş sorgular veya prepared statements ile değiştirin.

ORM otomatik olarak SQL Injection'dan korur mu?

ORM çerçeveleri yalnızca Sorgu Oluşturucu yöntemlerini ve adlandırılmış parametreleri kullandığınızda otomatik olarak korur. Ham sorgular (JPA'da nativeQuery, Room'da rawQuery) kullanıyorsanız, koruma çalışmaz — parametreleri dize birleştirmesi yoluyla değil, hazırlanmış ifadeler aracılığıyla iletmeniz gerekir.

Second-Order SQL Injection nedir?

Second-Order SQL Injection, kötü amaçlı verilerin veritabanında güvenli bir şekilde depolandığı ancak daha sonra kaçış olmadan başka bir sorguda kullanıldığı bir saldırıdır. Örneğin, bir saldırgan ' OR '1'='1 gibi bir kullanıcı adıyla kaydolur. Veriler bir dize olarak kaydedilir — kayıt sırasında saldırı olmaz. Ancak başka bir sorgu, parametreleştirme olmadan SQL'de bu kullanıcı adını kullanırsa, enjeksiyon tetiklenir.

NoSQL Injection, SQL Injection'dan daha tehlikeli olabilir mi?

NoSQL Injection, geliştirici farkındalığının daha düşük olması nedeniyle potansiyel olarak daha tehlikeli olabilir. Geliştiriciler SQL Injection'ı bilir ve çoğu ORM kullanır, ancak çok azı NoSQL Injection'ı bilir. MongoDB'de yanlış biçimlendirilmiş bir sorgu, bir koleksiyondaki tüm belgeleri döndürebilir. Koruma aynıdır — prepared statements (BSON parametreleştirmesi) ve sıkı giriş doğrulaması.

Özet

  • SQL Injection — DB sorgularında kaçış yapılmamış kullanıcı parametreleri aracılığıyla SQL kodu enjekte eden bir saldırı
  • Ana Türler — In-band (klasik), Blind (kör, zaman tabanlı), Out-of-band (harici kanal aracılığıyla)
  • Sorgu Parametreleştirmesi — SQL Injection'a karşı tek %100 güvenilir koruma yöntemi
  • ORM Efsanesi — ORM yalnızca yerleşik yöntemler kullanıldığında korur; birleştirmeli ham sorgular hala savunmasızdır
  • En Az Ayrıcalık İlkesi — DB hesap ayrıcalıklarını sınırlamak, başarılı bir saldırı durumunda hasarı en aza indirir
  • Düzenli Test — sqlmap, OWASP ZAP, SonarQube CI/CD hattının bir parçası olmalıdır
  • Yerel SQLite — mobil uygulamalar da yerel veritabanı sorgularını parametreleştirmelidir

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun