Dinamik Sorgu — Filtre Ekranı Bir Kapıya Dönüşmesin
Önce şunu oku: join fetch ve Sayfalama — 10 Sipariş İçin Bütün Tablo
30 saniyede özet
Müşteri filtrelerin istediğini doldurur, istediğini boş bırakır. Sorguyu metin birleştirerek kurmak SQL injection kapısı açar, her kombinasyona bir metot yazmak sayıyı katlar. Çözüm: filtre başına bir Specification parçası.
Bir sandviççide sipariş fişi dolduruyorsun: peynir olsun, domates olmasın, bir de not. Fiş kutulu olduğu sürece sorun yok. Ama sipariş tek bir serbest cümle olsaydı, biri sonuna “ve kasayı da ver” yazabilirdi.
-
Bayt: Hareketler sayfasına filtre ekledim: kategori, tutar, tarih, açıklama. Sorguyu if'lerle kurup birleştiriyorum.
-
Sen: Bir müşteri açıklama kutusuna tırnaklı bir şey yazmış ve bütün bankanın hareketlerini görmüş.
-
Bayt: Ama sorguda account_id koşulu vardı!
-
Bayt: Vardı. Sonra müşterinin yazdığı metin sorgunun bir parçası oldu ve o koşulu etkisiz bıraktı.
Metin birleştirmek neden tehlikeli?
Filtre ekranında her filtre isteğe bağlıdır; sorgu kullanıcının doldurduğuna göre değişir. En kolay görünen yol, dolu filtreleri " AND description LIKE '%" + text + "%'" gibi metne eklemektir.
Müşteri kutuya x' OR 1=1 -- yazarsa tırnak kapanır, OR 1=1 eklenir ve sorgunun geri kalanı yorum olur. Buna SQL injectionKullanıcının yazdığı metnin sorgu metnine karışıp sorgunun yapısını değiştirmesi. Değer bağlı parametre olarak gönderilince olamaz.Sözlükte gör → denir; hesap koşulu artık hiçbir şeyi sınırlamaz.
Kafam karıştı, daha basit anlat
Müşterinin yazdığı metni sorgu metnine yapıştırırsan, sorguyu müşteri de değiştirebilir.
SQL injection nedir?
Sorguya " AND description LIKE '%" + text + "%'" eklendi. Müşteri x' OR 1=1 -- yazdı. Ne olur?
Kutulu fiş: filtre başına bir parça
Güvenli olsun diye her filtre kombinasyonu için ayrı bir repository metodu yazdık. Dört isteğe bağlı filtre var, ürün ekibi beşincisini istedi. Kaç metot olur? Cevabı göster
31. n isteğe bağlı filtrenin boş olmayan 2^n - 1 kombinasyonu vardır: dört filtre için 15, beş için 31. Güvenli, ama her yeni filtre sayıyı ikiye katlar.
Adım adım oku
- Sipariş tek bir serbest cümle: sonuna kasayı da ver yazılabilir.
- Her kombinasyona ayrı menü: bitmez.
- Malzeme başına bir kutu, işaretli olan sayılır.
- Kutudaki yazı sadece yazıdır.
Değer sorgu metnine değil, bir bağlı parametreSorgu metninde yalnızca bir yer tutucu (?) bulunur, değer ayrıca gönderilir. Veritabanı değeri hiçbir zaman sorgunun parçası olarak okumaz.Sözlükte gör → gider: sorguda yalnızca ? vardır, değer ayrıca yollanır. Veritabanı onu hiçbir zaman sorgunun parçası olarak okumaz.
Bir SpecificationSpring Data JPA'da tek bir filtre koşulunu anlatan küçük bir parça. Dolu filtrelerin parçaları çalışırken birleştirilir; Criteria API değerleri parametre olarak gönderir.Sözlükte gör →, tek bir filtreyi anlatan küçük bir parçadır. Dolu filtrelerin parçaları çalışırken birleştirilir; beş filtre beş parça demektir.
Kafam karıştı, daha basit anlat
Değer parametre olarak gider. Her filtre bir parça, yalnızca dolu olanlar birleştirilir.
Bağlı parametre (bind parameter) neden enjeksiyonu engeller?
Specification ile isteğe bağlı filtreler nasıl kurulur?
Kendin gör
Filtre ekranı: üç arama
Tohum 851951Oturum: TR01 · bakılacak repository metodu: 1
- 🔎 Kategori: MARKET
- 🔎 En az 1000 TL, 1 Ekim’den beri
- 🔎 Açıklama: x' OR 1=1 --
Şu an ne oldu?
Metni birleştirerek sorgu kur
4 isteğe bağlı filtre; müşteri istediğini doldurur, istediğini boş bırakır.
Görevler0/3
Bir müşteri bütün müşterilerin hareketlerini görsünaçık
İpucu
Değeri sorgu metnine yapıştır.
Sızıntı olmasın, ama bakılacak metot sayısı 30’u geçsinaçık
İpucu
Beşinci filtreyi ekle ve her kombinasyona bir metot yaz.
Beş filtrenin hepsi olsun, sızıntı olmasın, metot sayısı beşi geçmesinaçık
İpucu
Filtre başına bir parça.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. Üçüncü aramadaki tırnak, hesap koşulunu etkisiz bıraktı.
- “Her kombinasyona bir metot” seç. Sızıntı yok; metot sayısı 15.
- Beşinci filtreyi aç. Metot sayısı 31 oldu.
- “Specification” seç. Beş filtre beş parça; üçüncü aramada
x' OR 1=1 --yalnızca aranan bir metin.
Dört isteğe bağlı filtre için türetilmiş metotlar (findByAccountIdAndCategory…) yazıyoruz. Beşinci filtre gelince metot sayısı ne olur?
Filtre ekranında hesap koşulu nereden gelmeli?
Tuzaklar
JPQL’i güvenli sanmak. "... WHERE d.description LIKE '%" + text + "%'" JPQL’de de enjeksiyona açıktır. Parametre kullan.
Hesap filtresini istekten almak. Filtre ekranı “hangi hesap” diye sormamalı; o değer her zaman oturumdan gelir ve her sorguya eklenir.
Sıralama sütununu kullanıcıdan almak. ORDER BY parametre olamaz; kullanıcının seçtiği sütunu izinli bir listeyle eşleştir.
Kafam karıştı, daha basit anlat
JPQL’de de parametre kullan, hesabı oturumdan al, sıralama sütununu izinli listeden seç.
Kullanıcı sıralama sütununu seçebiliyor. Bunu nasıl güvenli yaparsın?
Derinleş · Hareket filtresi: beş isteğe bağlı filtre, tek güvenli sorgu 4 dosya · ~88 satır · ilk okumada atlayabilirsin
Kendini sına
Sorgu JPQL ile yazılmışsa metin birleştirmek güvenlidir.
Sorgu JPQL ile metin birleştirerek yazıldı. Güvenli mi?
Aklında kalacak üç şey
- 1 Kullanıcının yazdığı değeri sorgu metnine yapıştırmak, ona sorguyu değiştirme izni vermektir. Değer her zaman bağlı parametre olarak gider.
- 2 İsimden türetilen repository metotları sabit aramalar için iyidir. İsteğe bağlı n filtre için 2^n - 1 kombinasyon gerekir; yeni bir filtre sayıyı ikiye katlar.
- 3 Specification ile her filtre küçük bir parçadır; yalnızca dolu olanlar çalışırken birleştirilir. Hesap filtresi müşteriden değil, her zaman oturumdan gelir.
4 kart sonraki derste seni bekliyor
Bu dersin üstüne kurulanlar
Bunlar bu dersi temel alıyor; hazır olduğunda devam edebilirsin.