it-swarm.it

Iniezioni SQL usando Jfactory :: getDBO e setQuery ()

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

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

SetQuery () genererà un errore per avere due istruzioni SQL nella stessa stringa?

Ad esempio, secondo il mio codice, è possibile eseguire un comando drop table passando questo parametro di query o qualcosa di simile:

key=a'; DROP TABLE people; # 

Inoltre userà qualcosa di simile

$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);

impedire l'iniezione poiché il limite di query dell'oggetto query è impostato su 1?

5
Jay Shri

Non dovrai preoccuparti degli attacchi di iniezione sql se usi quote() (o q()) e quoteName() (o qn()) metodi in modo appropriato.

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

Sicuro sulla ricerca

Un'attenzione particolare dovrebbe essere prestata alle clausole LIKE che contengono il carattere jolly% in quanto richiedono una fuga speciale per evitare possibili attacchi denial of service. Le clausole LIKE possono essere gestite in questo modo:

// Costruisci il termine di ricerca eseguendo l'escape della stringa fornita dall'utente e, se necessario, aggiungendo manualmente i caratteri jolly%.

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

// Costruisci la query SQL, facendo attenzione a sopprimere il comportamento predefinito di Quote in modo da evitare il doppio escape.

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

->like(), per quanto ho studiato, non esiste. Quindi, in base alla raccomandazione di documentazione sopra e supponendo che tu voglia cercare nella colonna name, suggerirò il seguente blocco di codice:

$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);

Quando si esegue una query LIKE è spesso logico ricevere più righe di dati nel gruppo di risultati. Poiché credo che tu stia semplicemente usando il metodo setLimit() come precauzione di sicurezza, lo rimuoverò per motivi di query migliorata.


Nonostante ciò il commento di inf3rno afferma, non esiste un metodo bind() disponibile secondo l'ultima documentazione . (Ho testato comunque lo snippet utilizzando sia :needle Che ? Come segnaposto e ricevuto: Errore irreversibile: chiamata a un bind di funzione membro () su null) I Vorrei che non fosse così perché prima di entrare in Joomla-land, avrei usato dichiarazioni preparate con segnaposto per TUTTI i dati esterni/non affidabili forniti alle mie domande.

n post pertinente di Lodder dal 2014 riguardo alle dichiarazioni preparate in Joomla.

L'intento/effetto del metodo quote (escape ()) nel mio blocco di codice sopra è quello di garantire che, indipendentemente dalla stringa che viene passata alla query, la stringa viene sempre trattata come un singolo valore nell'espressione. Sembra l'equivalente di mysqli_real_escape() (ma non ho controllato sotto il cofano di Joomla). Sfortunatamente, molti sviluppatori StackOverflow contrassegnano mysqli_real_escape() come non ottimale e raccomandano invece istruzioni preparate con segnaposto. Aggiornerò tutti i miei progetti Joomla non appena sarà disponibile il metodo bind().


Ho eseguito il seguente test sul mio Joomla 3.8.6:

$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();
}

e ha ricevuto:

1064 Hai un errore nella sintassi SQL; controlla il manuale corrispondente alla versione del tuo server MySQL per la sintassi corretta da usare vicino a 'INSERT INTO

Questo indica che il metodo Joomla setQuery() si strozzerà su più query.

6
mickmackusa