web-gelistirme-sc.com

Jfactory :: getDBO ve setQuery () kullanarak SQL enjeksiyonları

$db = JFactory::getDBO();
$searchP = JRequest::getVar('key');
$sql = "SELECT name FROM people LIKE " . "'%" . $searchP . "%'";

$db->setQuery($sql);
$fileR = $db->loadObjectList();

SetQuery () aynı dizede iki SQL ifadesi olması için bir hata atar mı?

Örneğin, koduma göre, bu sorgu parametresini veya benzer bir şeyi geçirerek bir açılan tablo komutu yürütmek mümkün mü:

key=a'; DROP TABLE people; # 

Ayrıca,

$db = JFactory::getDBO();
$query = $db->getQuery(true); 
$query ->setLimit('1');
$query ->select($db->quoteName('name'));
$query ->from($db->quoteName('people'));
$query ->like($db->quoteName($searchP));
$db->setQuery($query);

sorgu nesnesinin sorgu sınırı 1 olarak ayarlandığından enjeksiyon önleme?

5
Jay Shri

quote() (veya q()) ve quoteName() (veya qn()) kullanırsanız sql enjeksiyon saldırıları hakkında endişelenmenize gerek yoktur. yöntemleri uygun.

https://docs.joomla.org/Secure_coding_guidelines#Secure_on_search

Aramada güvenli

% Joker karakteri içeren LIKE yan tümcelerine özel dikkat gösterilmelidir, çünkü bunlar olası hizmet reddi saldırılarını önlemek için özel bir kaçış gerektirir. LIKE cümleleri şu şekilde kullanılabilir:

// Kullanıcı tarafından sağlanan dizeden kaçarak ve gerekirse% joker karakterlerini manuel olarak ekleyerek arama terimini oluşturun.

$search = '%' . $db->escape( $search, true ) . '%' );

// SQL sorgusu, çift kaçış önlemek için Alıntı varsayılan davranış bastırmak için dikkatli olun.

$query = 'SELECT  * FROM #__table WHERE `field` LIKE ' . $db->quote( $search, false );

->like(), araştırdığım kadarıyla mevcut değil. Bu nedenle, yukarıdaki dokümantasyon önerisine dayanarak ve name sütununu aramak istediğinizi varsayarsak, aşağıdaki kod bloğunu önereceğim:

$db = JFactory::getDBO();
$query = $db->getQuery(true)
            ->select($db->qn('name'))
            ->from($db->qn('people'))
            ->where($db->qn('name') . ' LIKE ' . $db->q('%' . $db->escape($searchP, true) . '%', false));
$db->setQuery($query);

Bir LIKE sorgusu gerçekleştirirken, sonuç kümesinde birden çok veri satırı almak genellikle mantıklıdır. Güvenlik önlemi olarak yalnızca setLimit() yöntemini kullandığınıza inandığım için, gelişmiş sorgulama amacıyla onu kaldıracağım.


inf3rno'nun yorum durumlarına rağmen, en son Belgeler 'a göre bind() yöntemi yoktur. (Snippet'i her iki şekilde de :needle Ve ? Kullanarak yer tutucu olarak test ettim ve aldım: Önemli hata: null üzerinde bind () işlevine çağrı diliyorum bu şekilde değildi çünkü Joomla-land'a girmeden önce, sorgularıma beslenen TÜM harici/güvenilmez veriler için yer tutucularla hazırlanmış ifadeler kullanacağım.

Joomla'da hazırlanan açıklamalarla ilgili olarak Lodder'dan 2014 tarihli ilgili bir yazı .

Yukarıdaki kod bloğumdaki quote (escape ()) yönteminin amacı/etkisi, sorguya hangi dize iletilirse iletilsin, dize her zaman ifadede tek bir değer olarak ele alınır. Bu mysqli_real_escape() eşdeğeri gibi görünüyor (ama Joomla başlık altında kontrol etmedim). Ne yazık ki, pek çok StackOverflow geliştiricisi mysqli_real_escape() öğesini en uygun olmayan olarak işaretler ve bunun yerine hazırlanmış ifadeleri yer tutucularla önerir. bind() yöntemi kullanılabilir olur olmaz tüm Joomla projelerimi güncelleyeceğim.


Joomla 3.8.6'da şu testi yaptım:

$needle = "key=a'; INSERT INTO [... redacted query that would be successful on its own ...]; #";
try {
    $db = JFactory::getDbo();
    $sql = "SELECT [redacted] FROM [redacted] WHERE [redacted] LIKE " . "'%" . $needle . "%'";
    $db->setQuery($sql);
    var_export($db->loadAssocList());
} catch (Exception $e) {
    echo $e->getMessage();
}

ve alındı:

1064 SQL sözdiziminizde bir hata var; 'INSERT INTO yakınında kullanılacak doğru sözdizimi için MySQL sunucu sürümünüze karşılık gelen kılavuza bakın

Bu, Joomla'nın setQuery() yönteminin birden çok sorguda boğulacağını gösterir.

7
mickmackusa