Parametreli sorgulara güvenmek SQL enjeksiyonuna karşı korumanın tek yolu mudur?


13

SQL enjeksiyon saldırılarında gördüğüm tek şey, parametreli sorguların, özellikle de saklı yordamlardaki sorguların, bu tür saldırılara karşı korunmanın tek yolu olduğunu gösteriyor. Çalışırken (Karanlık Çağlarda) depolanmış prosedürler, daha az bakım yapılabilir oldukları için kötü uygulama olarak görülüyordu; daha az test edilebilir; yüksek derecede birleşmiş; ve bir sistemi tek bir satıcıya kilitledi; ( bu soru başka nedenleri de kapsamaktadır).

Çalışırken, projeler bu tür saldırıların olasılığından neredeyse habersizdi; veritabanını çeşitli türlerin bozulmasına karşı korumak için çeşitli kurallar kabul edilmiştir. Bu kurallar şöyle özetlenebilir:

  1. Hiçbir istemci / uygulamanın veritabanı tablolarına doğrudan erişimi yoktu.
  2. Tüm tablolara tüm erişim görünümler aracılığıyla (ve temel tablolarda tüm güncellemeler tetikleyiciler aracılığıyla yapıldı).
  3. Tüm veri öğelerinin bir etki alanı belirtildi.
  4. Hiçbir veri öğesinin boş bırakılmasına izin verilmiyordu - bunun, DBA'ların zaman zaman dişlerini taşlamasıyla ilgili sonuçları vardı; ama zorunlu kılındı.
  5. Roller ve izinler uygun şekilde ayarlandı - örneğin, görünümlere yalnızca verileri değiştirme hakkını veren sınırlı bir rol.

Öyleyse, bu tür (zorunlu olarak bu özel küme olmasa da) gibi bir dizi kural, SQL enjeksiyon saldırılarını önlemede parametrelenmiş sorgulara uygun bir alternatif mi? Değilse, neden olmasın? Bir veritabanı (yalnızca) belirli önlemlerle bu tür saldırılara karşı güvence altına alınabilir mi?

DÜZENLE

Sorunun vurgusu, alınan ilk yanıtlar ışığında biraz değişti. Temel soru değişmedi.

EDIT2

Parametreleştirilmiş sorgulara güvenme yaklaşımı, sistemlere yönelik saldırılara karşı savunmada sadece periferik bir adım gibi görünmektedir. Bana göre, daha temel savunmaların her ikisi de arzu edilir ve özellikle enjeksiyon saldırılarına karşı savunmak için bile gerekli olmayan veya daha az kritik olan bu tür sorgulara güvenebilir.

Benim sorum örtük yaklaşım veritabanı "zırh" dayanıyordu ve bu geçerli bir seçenek olup olmadığı hakkında hiçbir fikrim yoktu. Daha fazla araştırma, bu tür yaklaşımların olduğunu ileri sürdü. Bu tür yaklaşıma bazı işaretler sağlayan aşağıdaki kaynakları buldum:

http://database-programmer.blogspot.com

http://thehelsinkideclaration.blogspot.com

Bu kaynaklardan aldığım temel özellikler:

  1. Kapsamlı bir veri sözlüğü ile birlikte kapsamlı bir veri sözlüğü
  2. Veri sözlüğünden tetikleyiciler, sorgular ve kısıtlamalar oluşturma
  3. Kodu En Aza İndir ve Verileri En Üst Düzeye Çıkar

Şimdiye kadar aldığım cevaplar çok faydalı olsa da ve paramaterize sorguları göz ardı etmekten kaynaklanan zorluklara işaret ederken, sonuçta orijinal sorularıma cevap vermiyorlar (şimdi kalın harflerle vurgulanmıştır).


Saklı yordamlara karşı argüman almıyorum. Sadece doğru değiller.
Konrad Rudolph

Boş değer gereksinimi nedir?
Mark Canlas

2
@Konrad Rudolph - Uygulamanızı MySQL üzerine yazar ve sonra DB2'ye geçmeye karar verirseniz, saklı yordamların uyumlu olacağını düşünüyor musunuz? Aynı şekilde SQLLite'a geçmek istiyorsanız? Ayrıca, işletim sisteminizi yükselttiğinizi varsayalım - saklı yordamlarınız C'de derlenmişse (DB2'de olduklarını), muhtemelen hepsinin yeniden derlenmesi gerekir. Bunlar makul argümanlardır - mutlak değil, makul.
Matthew Flynn

@Matthew Duh. Bunu okurken ve hakkında yorum yaparken aslında “parametrik sorgular” düşünüyordum. Saklı yordam = bütün 'nother hikaye.
Konrad Rudolph

Yanıtlar:


25

Saklanan procs, enjeksiyona karşı otomatik olarak koruma sağlamaz. Peki buna ne dersin

CREATE PROC proc
  @id VARCHAR(5)
AS
BEGIN
  EXEC("SELECT * FROM Client WHERE ClientId = " + @id);
END

Parametreli sorgular kullanmak, ister procs olsun ister olmasın, sizi enjeksiyona karşı korur.


Procs yerine parametrelenmiş sorgulara odaklandığınız için teşekkür ederiz. Ancak, veritabanının bu tür sorgular dışında yöntemlerle korunup korunamayacağını soruyorum - özellikle yalnızca veritabanı katmanıyla sınırlı yöntemler.
Chris Walton

1
+1 Buna ek olarak, saklanan proc'ların çoğunlukla güvenli kabul edildiğini belirtmek isterim çünkü bu, verileri almak için bir yol sürdürürken kullanıcıların doğrudan tablolara erişmesini önlemenin tek yoludur. Kullanıcının, müşterisiyle aralarında hiçbir şey olmadan doğrudan veritabanı erişimine sahip olması gerektiğinde satır ve sütun tabanlı ayrıcalıkların sağlanmasının tek yolu budur.
Falcon

2
@Chris - Bence Craig'in burada söylediği şey, procs'ların sizi gerçekten koruduğunu varsayamayacağınızdır. Belki de tam bir cevap değil, başlıktaki varsayımın daha fazla düzeltilmesi.
Jon Hopkins

@Jon - Craig'in düzeltmesi ışığında sorunun başlığını değiştirdim ve soruda bazı düzenlemeler yaptım. Cevap almaya başlayana kadar soruda yaptığım varsayımın farkında değildim.
Chris Walton

2
Craig yukarıda yazdıkları pekiştirmek için, bkz databasesecurity.com/dbsec/lateral-sql-injection.pdf : "Oracle Açığı Yeni Bir Sınıf Yanal SQL Injection"
Bruce Ediger

11

Peki bunun gibi bir dizi (zorunlu) kural SQL enjeksiyon saldırılarını önlemede saklı yordamlara uygun bir alternatif mi? Değilse, neden olmasın?

Hayır, çünkü geliştiricilere ağır bir ceza veriyorlar. Öğe başına döküm:

1. Hiçbir istemci / uygulamanın veritabanı tablolarına doğrudan erişimi yoktu.

Rolleri kullanın. İstemciler DB'ye yalnızca erişmesi gereken tablolara (ve mümkünse satırlara) SELECT, INSERT, UPDATE ve DELETE erişimi olan sınırlı bir rolle erişebilmelidir. Hiçbir istemcinin tüm girişlere spam gönderemeyeceğinden veya sildiğinden emin olmak istemiyorsanız, veri değişikliği için bir API kullanın.

2. Tüm tablolara tüm erişimler görünümler aracılığıyla oldu.

Bu, görüşlerin verimliliğine bağlı olarak ihmal edilebilirden büyük bir performans maliyetine kadar her şey olabilir. Gelişimi yavaşlatan gereksiz karmaşıklıktır. Rolleri kullanın.

3. Tüm veri öğelerinin bir etki alanı belirtildi.

Sürdürülmesi gereken çok iş olabilir ve muhtemelen ayrı bir tabloya normalleştirilmelidir.

4. Hiçbir veri öğesinin boş bırakılmasına izin verilmemiştir - bunun, DBA'ların zaman zaman dişlerini taşlamasıyla ilgili sonuçları vardı; ama zorunlu kılındı.

Bu sadece yanlış. Eğer geliştiriciler başa çıkamıyorsa NULLbüyük problemleriniz var.

Bir veritabanı (yalnızca) belirli önlemlerle bu tür saldırılara karşı güvence altına alınabilir mi?

Sen do not sadece kullanmak, saklı yordamlar ihtiyaç parametrized sorgular gibi argümanlar, kaçar bir işlevle pg_query_params . Tabii ki, veritabanınız dünya çapında yazılabilirse veya istemci rolü her şeye tam erişime sahipse, zaten mahvoldunuz. Birisi gelip müşterinin ne yaptığını fark etmeli ve daha sonra DB'nizi yok eden (veya daha da kötüsü) zehirleri beş dakika içinde pişirmelidir.



Roller için +1. Bu konuda önemli bir katkıda bulunuyorlar - soruma rol dahil etmedim, ancak kurulumun bir parçasıydı - özellikle görünümlere müşteriler için önerdiğiniz gibi kısıtlı bir rol verildi. Görüntülemelerin performans isabeti üzerine gelinen nokta. Etki alanlarında doğrulama testleri - aralıklar ve çoğunlukla uzunluk vardı. Null veri kuralı hakkındaki yorumlarınız, bu kural hakkında duyduğumlardan çok daha kibar. Bu benim varsayımım olmasına rağmen izinlerin uygun şekilde oluşturulacağını açıkça belirtmedim.
Chris Walton

6

Kurallarınızın sizi tamamen koruduğundan emin değilim.

İlk sorun, zorlandıklarını belirtmenizdir, ancak önemli bir ek yük ile gelmenin yanı sıra, asla mükemmel bir uygulama görmedim.

İkincisi, onları okuduğumda, bu tür kuralların işleri sömürmeyi zorlaştırabileceği, ancak önleyemedikleri. Örneğin, görünümler aynı verilere erişmenize izin veriyorsa tablolara doğrudan erişimin olmaması çok fazla değişmez. İstemcinin bir şey yapması gerekiyorsa, bir görünümün bunu kolaylaştırması gerekir ve bir görünüm bunu kolaylaştırırsa, saldırgan tarafından aynı işlevsellik / veriler kullanılabilir.

Bunun yalnızca verileri güncellemek veya silmekle ilgili olmadığını da unutmayın. SQL enjeksiyonuyla ilgili güvenlik açığının bir kısmı bilgi toplamadır ve bunun için vCustomers (Müşteri) veya altta yatan Müşteriler tablosundan verilerin geri aktarılıp aktarılmadığı önemli değildir. Sen olabilir ancak tüm bazı zayıflıklar kendinizi korumuş. Benzer şekilde, güncellemeler istemci tarafından yapılabiliyorsa, tetikleyiciler aracılığıyla bile olsa, tetikleyicileri tetiklemek ve güncellemeler yapmak için SQL yazılabilir.

(Tetikleyiciler aracılığıyla yapılan tüm güncellemeler açısından iki şey söyleyeceğim: (1) bunu okuduğumda ağzımda biraz hasta oldum ve (b) Saklı Yordamları sevmiyorsunuz çünkü ' "daha az bakım yapılabilir, daha az test edilebilir; yüksek derecede birleştiğinde ve bir sistemi tek bir satıcıya kilitlediyseniz", ancak aynı şeylerin temel olarak söylenebileceği tetikleyiciler kullanırsınız.)

İhtiyacınız olan tek şey, SQL ifadelerinin yürütülmesine izin veren bir deliktir (ve bunu önleyen bu kurallardan hiçbirini görmüyorum) ve saldırgan içeride. Arkalarında çok sezgisel olmayan bir veritabanı buluyor olabilirler, ancak sadece yavaşlatmak yerine yavaşlatır).

Buradaki başka bir şey de karmaşıklık eklediğiniz ve (hem de oluşturan yükün yanı sıra) karmaşıklıktan yararlanabileceğiniz deliklere yol açma eğiliminde olmasıdır.

Böyle bir kurallar dizisinin yaratılamayacağını söylemiyorum - daha fazla neden rahatsız edesin ki? Bu tür saldırıları önlemek için yaygın olarak kabul edilen yöntemlerle gitmekten daha hantal ve daha az güvenilir görünüyorlar.


+1, gerçek sorgumu dolaylı, bilinçsiz varsayımlarım ışığında ve doğru şekilde yanıtladığım için. Neden biri rahatsız olabilir - Ben mimarinin ilgili bir açıklama kodu çoğaltılacak bir proje üzerinde çalışıyorum - ve bu mimarinin bir kısmı nasıl veritabanı erişim rutinleri oluşturmak açıklar. Bu oluşturulan rutinlerin nasıl bir şekil alacağı hala açık.
Chris Walton
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.