Zend Framework'ün SQL modellerini kullanırken SQL enjeksiyon güvenlik açıkları


15

Tablolara katılırken, Zend Framework'ün SQL modellerini kullanıyorum. Örnek olarak, gerçek kodumu değiştirdim, ama bence puan alacaksınız:

$this->getSelect()->join(
                      array('sections' => $sectionsTableName),
                      'main_table.banner_id = pages.banner_id',
                      array()
                    )
                  ->where("sections.section= '$section' OR sections.section = '0' OR (sections.section = '6' AND ? LIKE main_table.url)",$url)
                  ->group('main_table.banner_id'); 

Sayfa ajax ile yüklenir ve $ section parametresi GET parametresi ( www.example.com/controllerName/index/display/3?paremeter1=example&section=www.example2.com) olarak gönderilir .

Birisi böyle bir şey yaparsa sorun şu:

www.example.com/controllerName/index/display/3?paremeter1=example&url=(SELECT 3630 FROM(SELECT COUNT(*),CONCAT(0x7170786a71,(SELECT (ELT(3630=3630,1))),0x717a716b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)

Bu şekilde kullanıcı tüm veritabanını dökebilir. Veriler görüntülenmez, ancak SQL sql aşırı yüklenmesine neden olabilecek bir döküm gerçekleştirir.

Sorular:

  1. Bu senaryoyu önlemenin en iyi yolu nedir?
  2. Şimdi önceki müşteriler için endişeliyim. Bu kodla, tabloyu değiştirme veya değiştirme gibi daha fazla riskli işlem yapmak mümkün müdür? Sanırım DELETE sql sözdizimi hatası üretmek için alt seçim içinde SELECT dışında başka bir ifade koyamazsınız değil. Haklı mıyım?

GÜNCELLEME: Benim örneğim SQL enjeksiyonunun doğru bir örneği değil çünkü $ bölümleri etrafında işaret var ve bu nedenle enjeksiyon yapmak mümkün olmayacak. Her neyse, tamsayı değeri beklenirken ve tamsayı girişine filtre uygulamadığınızda bu mümkün olabilir. Aşağıdaki yorumuma bakın.


1
Sen kullanabilirsiniz: $db = Mage::getSingleton('core/resource')->getConnection('core_read');ve $db->quote()hatta senin durumunda bak $db->quoteInto. Eğer $thisbir kaynaktır, bunu yapabilirsiniz: $this->getConnection('core_read')->quoteInto()Bir koleksiyon eğer yapabilirdi: $this->getResource()->getConnection('core_read')->quoteInto(). bu çizgiler boyunca. Bu sizi hedefinize doğru yönlendirirse.
ash

Ben sadece bu senaryo sadece değer tamsayı ise mümkün olduğunu fark ettim. Değer varchar ise, her zaman 'işaretten önce (işaret olacaktır ve bu nedenle (SELECTya da herhangi bir şey işlev değil, dize gibi olacaktır. Alan tamsayı olduğunda, 'gerekli değildir ve bu tür bir senaryoyu mümkün kılar. Ancak tamsayı her zaman filtrelenmelidir, intval()böylece bu da sorun değildir.
JohnyFree

Ya kapatmaya başlarsanız '? Yani ' AND (SELECT ...) '? Bu arada, Zend'in bunu alıntılamadığını sanmıyorum ... Ve eğer bağlamaları kullanırsanız, PDO bunu halledecektir. Asla böyle acı birleştirme kullanmayın:"sections.section= '$section'"
7ochem

@ 7ochem bu durumda kullanarak parametre bağlamak GEREKİR? ve 'olacak'. Ancak tamsayı değeri kullanırsanız, intval () php işlevini kullanarak temizleyebileceğiniz ve 'bir şey 0 olacaktır.
43'te JohnyFree

Yanıtlar:


8

Girişinizi doğrulayın!

Mümkün olduğunca iyi ve mümkün.

Doğrulamanız için bazı öneriler:

  1. GET parametresi aracılığıyla aldığınız değişkenin uzunluğunu kontrol edin. Hiç bitmeyen uzun bir ipi kabul etmeye gerek yoktur.

  2. Bir alan adı için doğrulayın. Beklediğiniz alan adlarının biçimi nedir? Her zaman www.alanadım.tld mi? Bir eşleşmeyi veya (daha iyi) kullanımı kontrol eden bir normal ifade oluşturun Zend_Validate_Hostname:

    $validator = new Zend_Validate_Hostname();
    if ($validator->isValid($hostname)) {
        //hostname is valid - continue
    }
  3. Beyaz liste: Hangi alan adlarının bekleneceğini biliyor musunuz? İzin verilen alanların bir listesini oluşturabilir ve bunlara karşı kontrol edebilirsiniz. Gerisini bırakın.

    $allowedDomains = array('www.domain1.tld','www.domain2.tld');
  4. Alan adlarını ve / veya karakterleri kara listeye ekleme: Bir alan adı bekliyorsanız, az ve 0-9 ve "." Dışında herhangi bir karakteri kabul etmeye gerek yoktur. (özel alan adlarıyla çalışmadığınız sürece).

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.