Я не могу понять, почему сортировка будет работать до тех пор, пока я не использую $ sort как переданный параметр. Пример ниже будет работать для сортировки:
$sort = "quantity desc"; $sql = " with items as ( SELECT i.[item_id] ,i.[name] ,i.[value] ,i.[quantity] ,i.[available] ,isnull(r.awarded, 0) as awarded , ROW_NUMBER() OVER( ORDER BY $sort ) rowNumber FROM [Intranet].[dbo].[Goodwell_Item] i LEFT JOIN ( SELECT r.item_id , COUNT(1) awarded from [Intranet].[dbo].[Goodwell_Reward] r group by r.item_id ) as r ON i.item_id = r.item_id ) SELECT * FROM items WHERE rowNumber BETWEEN (?) and (?) and ( (?) = '' OR (available = (?))) "; $params = array( $pagify['startFrom'], $end, $available, $available ); $stmt = sqlsrv_query( $conn, $sql, $params );
Однако, если я сменил строку с ORDER BY на:
ORDER BY (?)
и добавьте его в мои $ params следующим образом:
$params = array($sort, $pagify['startFrom'], $end, $available, $available );
то сортировка по какой-то причине игнорируется.
Скажите, пожалуйста, как заставить сортировку работать таким образом, чтобы не разрешать SQL-инъекцию.
Я имею дело с этой точной проблемой прямо сейчас и не могу найти что-либо в Интернете, чтобы помочь.
Я пытался:
$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY ? "; $result = $conn->getData($query, array($seriesID,$sortBy));
а также
$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY ? ?"; $result = $conn->getData($query, array($seriesID,$sortBy,$sortOrder));
В обоих случаях я не получаю ошибки и никаких результатов.
Я считаю, что единственный способ решить эту проблему – использовать оператор switch перед запросом для ручной проверки допустимых значений. Однако, если вы не имеете дело только с одной таблицей, вы не можете знать, какие возможные значения для столбца SortBy.
Однако, если вы просто исходите из предположения, что значения на этом этапе уже были очищены, вы можете пойти с непараметрированной версией следующим образом:
$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY " . $sortBy . " " . $sortOrder; $result = $conn->getData($query, array($seriesID));
То, что я планирую сделать, это убедиться, что вы проверяете sortBy и sortOrder, прежде чем передавать их методу, содержащему этот код. Таким образом, каждое место, которое я вызываю, становится ответственным за проверку данных перед его отправкой. Вызывающий код будет знать допустимые возможные значения для таблицы (или просмотра в этом случае), которые она вызывает. (В этом случае я являюсь автором обоих фрагментов кода, поэтому я знаю, что это безопасно.)
Итак, короче говоря, просто убедитесь, что значения в этой точке кода уже очищены и безопасны, и надавите на эту ответственность на один уровень код, который вызывает этот код.