Örnek sorular
As Injection Input ValidationZorluk 1
Bir sorgu, kullanıcı adını doğrudan string'e ekleyerek SQL oluşturuyor: "SELECT FROM users WHERE name = '" + name + "'". Başka bir sorgu ise parametrize edilmiş bir sorgu kullanıyor: "SELECT FROM users WHERE name = ?" ve name ayrıca bind ediliyor. İkincisi SQL injection'a karşı neden güvenli?
- aDaha hızlı çalıştığı için saldırganın bir şey enjekte etmeye zamanı olmaz
- bVeritabanı yalnızca ilk formdan daha kısa sorguları kabul eder
- cBind edilen değer veri olarak gönderilir, SQL sözdizimi olarak ayrıştırılmaz✓
- dPlaceholder'lar tüm tırnak karakterlerini otomatik olarak siler
Açıklama:Parametrize edilmiş sorguda SQL metni ile parametre değerleri veritabanına ayrı ayrı gider; sürücü name'i literal bir veri değeri olarak bağlar, bu yüzden içindeki ' gibi karakterler sorgunun yapısını asla değiştiremez. Concatenation ise SQL metninin kendisini güvenilmeyen girdiden inşa eder, saldırganın string'i kapatıp kendi cümlecikler eklemesine izin verir.
As Injection Input ValidationZorluk 2
Bir uygulama sorguların çoğu için ORM'in query builder'ını kullanıyor, ama bir rapor endpoint'i dinamik filtre oluşturmak için db.raw("SELECT * FROM orders WHERE status = '" + status + "'") çağırıyor. Başka yerlerde ORM kullanılması bu endpoint'i SQL injection'dan korur mu?
- aHayır, string concatenation ile
.raw() kullanımı ORM'in parametre bind mekanizmasını tamamen atlar✓ - bEvet, ORM'in bağlantı havuzu her string'i çalıştırmadan önce SQL sözdizimine benzeyen her karakter dizisini silerek sanitize eder
- cEvet, ORM'ler kullanıcı girdisi içeren her sorguyu reddeder
- dHayır, ama yalnızca tablo birden fazla sütuna sahipse
Açıklama:ORM'ler, kendi query-building API'niz kullanıldığında sizin yerinize parametre bind ederek SQL injection'ı önler. Ham SQL kaçış kapısına inip güvenilmeyen girdiyi concatenate etmek, elle yazılmış SQL ile tamamen aynı zafiyeti geri getirir — kodun geri kalanının ORM etiketi taşıması bu tek sorguya hiçbir koruma sağlamaz.
As Injection Input ValidationZorluk 2
Bir ekip, "uygulama kodundaki string ile kurulmuş SQL'den kurtulmak için" sorgu mantığını bir veritabanı stored procedure'üne taşıyor. Procedure içinde parametre hâlâ EXEC(@sql) ile dinamik bir SQL string'ine concatenate ediliyor. Stored procedure SQL injection'a karşı bağışık mı?
- aEvet, stored procedure'ler her zaman kısıtlanmış veritabanı yetkileriyle çalışır
- bEvet, stored procedure'ler string parametre kabul edemez
- cHayır, ama yalnızca trigger'lar procedure içindeki dinamik SQL derlenmeden önce tetiklendiği için
- dHayır, procedure içinde parametrelerden kurulan dinamik SQL yine enjekte edilebilir✓
Açıklama:Kodu bir stored procedure'e taşımak SQL'in NEREDE kurulduğunu değiştirir, NASIL kurulduğunu değil. Procedure'ün kendisi güvenilmeyen bir parametreyi bir string'e ekleyip sonra bunu EXEC(@sql) ile dinamik çalıştırıyorsa, uygulama seviyesinde string kurmayla aynı injection riski vardır. Güvenlik, procedure içinde de parametre bind kullanmaktan gelir, kodun veritabanında yaşamasından değil.
As Injection Input ValidationZorluk 1
Bir kod review'da, sayısal bir ürün ID'sinin tırnaksız concatenate edildiği bir sorgu işaretleniyor: "SELECT * FROM products WHERE id = " + productId. Kaçılacak tırnak olmamasına rağmen bu neden yine SQL injection olabilir?
- aSayısal alanlar asla metin kabul etmediği için enjekte edilemez
- bSayısal bağlamda tırnak gerekmez,
1 OR 1=1 olduğu gibi enjekte olur✓ - cYalnızca sütun kayan noktalı sayı tipindeyse istismar edilebilir
- dSayısal concatenation her zaman veritabanı sürücüsü tarafından otomatik olarak bir stored procedure çağrısına dönüştürülür
Açıklama:Tırnak kaçışı string bağlamları için önemlidir, ama sayısal bağlamda tırnağa hiç gerek yoktur — ham girdi doğrudan SQL'e eklenir. 1 OR 1=1 (ya da daha kötüsü, bir subquery/UNION) gönderen bir saldırgan, hiç tırnak karakterine ihtiyaç duymadan sorgunun mantığını değiştirir; bu yüzden tırnaksız sayısal concatenation, tırnaklı string concatenation kadar güvensizdir.
As Injection Input ValidationZorluk 2
Bir login formunun backend'i "SELECT * FROM users WHERE username = '" + user + "' AND password = '" + pass + "'" sorgusunu kuruyor. Saldırgan kullanıcı adı olarak admin' -- gönderiyor, parola alanını boş bırakıyor. -- dizisi çoğu SQL dilinde ne etki yapar?
- aBir yorum başlatır, bu yüzden o satırın geri kalanı — parola kontrolü dahil — göz ardı edilir✓
- bSonraki karakterleri kaçışlar, onları literal metin haline getirir
- cKullanıcı adından bağımsız olarak sorgunun sıfır satır döndürmesini zorlar
- dHer SQL dilinde geçersiz sözdizimidir, veritabanı sorgunun tamamını doğrudan reddeder
Açıklama:-- çoğu SQL dilinde satır içi bir yorum başlatır, bu yüzden o satırdaki her şey — AND password = '...' dahil — parser tarafından atılır. Ortaya çıkan sorgu fiilen WHERE username = 'admin' haline gelir ve geçerli bir parola olmadan admin olarak kimlik doğrulanır; bu yüzden kaçışlanmamış girdinin sorgu metnine ulaşması, sadece tırnaktan çıkmanın ötesinde tehlikelidir.
As Injection Input ValidationZorluk 2
Bir geliştirici kullanıcı girdisini sayfaya eklemeden önce HTML-encode ediyor (< < oluyor, vb.) ve encode edilmiş string'i bir <script> bloğuna var name = "{{ encoded_name }}"; şeklinde ekliyor. HTML encoding uygulanmış olmasına rağmen bu neden hâlâ istismar edilebilir?
- aHTML encoding, script bloğu çalışmadan önce tarayıcının JavaScript motoru tarafından otomatik olarak geri çevrilir
- b
<script> etiketi tasarım gereği tüm encoding kurallarını görmezden gelir - cİstismar edilemez; HTML encoding her render bağlamını kapsar
- dJavaScript string'lerinin
" ve \ gibi kendi tehlikeli karakterleri vardır, HTML encoding bunları etkilemez✓
Açıklama:Output encoding, verinin düştüğü bağlamla eşleşmelidir. HTML encoding, HTML markup için <, >, & ve tırnakları etkisizleştirir, ama bir JavaScript string literal'i içinde tehlikeli olan karakterler kaçışlanmamış ", ', \ ve satır sonlandırıcılar gibi şeylerdir — HTML entity encoding bunlara dokunmaz. "; alert(1); // gönderen bir saldırgan string'i kapatıp HTML encoding'in hiç ele almadığı script'i enjekte edebilir.