Вам необходимо деконструировать сортировочную строку и проверить все ее части на белый список разрешенных терминов.
См. Следующий псевдокод.Я не полностью проверил это, но допустим, что это идея, которая имеет значение.
DELIMITER $$
CREATE PROCEDURE `get_users`(IN sortstring TEXT)
BEGIN
//check sortstring against a whitelist of allowed sortstrings
DECLARE sortpart VARCHAR(255);
DECLARE done BOOLEAN DEFAULT false;
DECLARE allok BOOLEAN DEFAULT true;
DECLARE i INTEGER DEFAULT 1;
WHILE ((NOT done) AND allOK) DO
SET sortpart = SUBSTRING_INDEX(sortstring,',',i);
SET i = i + 1;
SET done = (sortpart IS NULL);
IF NOT DONE THEN
SELECT 1 INTO allok WHERE EXISTS
(SELECT 1 FROM whitelist
WHERE allowed_sort_claused = sortpart AND tablename = 'users');
END IF
END WHILE;
IF allOK THEN
PREPARE statement FROM
CONCAT('SELECT username, passhashwithsalt FROM users ',sortstring);
EXECUTE statement;
DEALLOCATE PREPARE statement;
ELSE SELECT 'error' as username, 'error' as passhashwithsalt;
END IF;
END$$
См .: Как предотвратить внедрение SQL с динамическими именами таблиц?
Ошибка в вашем коде
Нельзя использовать имена столбцовили SQL-ключевые слова в качестве параметров.Вы можете использовать только значения в качестве параметров.По этой причине ваш запрос никогда не пройдет подготовку.
?
в SELECT x FROM t1 ?
будет просто заменен на SELECT x FROM t1 'ORDER BY field1, field2'
Что не имеет смысла.