$db = JFactory::getDBO();
$searchP = JRequest::getVar('key');
$sql = "SELECT name FROM people LIKE " . "'%" . $searchP . "%'";
$db->setQuery($sql);
$fileR = $db->loadObjectList();
SetQuery () lève-t-il une erreur pour avoir deux instructions SQL dans la même chaîne?
Par exemple, selon mon code, est-il possible d'exécuter une commande drop table en transmettant ce paramètre de requête ou quelque chose de similaire:
key=a'; DROP TABLE people; #
En outre, en utilisant quelque chose comme
$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);
empêcher l'injection puisque la limite de requête de l'objet de requête est définie sur 1?
Vous n'aurez pas à vous soucier des attaques par injection SQL si vous utilisez les fonctions quote()
(ou q()
) et quoteName()
(ou qn()
) méthodes de manière appropriée.
De https://docs.joomla.org/Secure_coding_guidelines#Secure_on_search
Sécurisé pour la recherche
Une attention particulière doit être portée aux clauses LIKE qui contiennent le caractère générique%, car elles nécessitent une évasion spéciale afin d'éviter d'éventuelles attaques par déni de service. Les clauses LIKE peuvent être traitées comme ceci:
// Construit le terme de recherche en échappant à la chaîne fournie par l'utilisateur et, si nécessaire, en ajoutant manuellement les caractères génériques%.
$search = '%' . $db->escape( $search, true ) . '%' );
// Construit la requête SQL en veillant à supprimer le comportement par défaut de Quote afin d'éviter le double échappement.
$query = 'SELECT * FROM #__table WHERE `field` LIKE ' . $db->quote( $search, false );
->like()
, dans la mesure où j'ai effectué des recherches, n'existe pas. Donc, sur la base de la recommandation de documentation ci-dessus et en supposant que vous souhaitiez effectuer une recherche dans la colonne name
, je vous suggère le bloc de code suivant:
$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);
Lors de l'exécution d'une requête LIKE
, il est souvent logique de recevoir plusieurs lignes de données dans l'ensemble de résultats. Puisque je crois que vous utilisiez simplement la méthode setLimit()
à titre de précaution de sécurité, je vais l'enlever afin d'améliorer les requêtes.
Malgré ce que commentaire de inf3rno indique, il n'y a pas de méthode bind()
disponible selon la dernière documentation . (J'ai testé l'extrait de toute façon en utilisant à la fois :needle
Et ?
Comme espaces réservés et j'ai reçu: Erreur fatale: appel de la fonction membre bind () sur null) I J'aurais aimé que ce ne soit pas le cas, car avant d'entrer dans Joomla-land, j'utilisais des instructions préparées avec des espaces réservés pour TOUTES les données externes/non fiables alimentées par mes requêtes.
n article pertinent de Lodder de 2014 concernant les déclarations préparées dans Joomla.
L'intention/effet de la méthode quote (escape ()) dans le bloc de code ci-dessus est de garantir que, quelle que soit la chaîne transmise à la requête, cette chaîne est toujours traitée comme une valeur unique dans l'expression. Cela ressemble à l'équivalent de mysqli_real_escape()
(mais je n'ai pas vérifié sous le capot Joomla). Malheureusement, de nombreux développeurs StackOverflow marquent mysqli_real_escape()
comme non optimale et recommandent plutôt des instructions préparées avec des espaces réservés. Je mettrai à jour tous mes projets Joomla dès que la méthode bind()
sera disponible.
J'ai exécuté le test suivant sur mon 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();
}
et reçu:
1064 Vous avez une erreur dans votre syntaxe SQL; Consultez le manuel correspondant à la version de votre serveur MySQL pour connaître la syntaxe à utiliser près de 'INSERT INTO.
Cela indique que la méthode setQuery()
de Joomla s'étouffera avec plusieurs requêtes.