Мой код работает, поэтому я чувствую себя грязным, задавая этот вопрос, но, похоже, я не могу найти нигде, используя такую же технику, поэтому хочу спросить, есть ли в нем что-то явно неправильное, чего я не вижу.
У меня есть хранимая процедура, в которой один входной параметр решает, какие поля возвращать, помещая его между SELECT и FROM ... в подготовленном операторе - я предполагаю, что это подвержено SQL-инъекции, поэтому я сканировал переменную, чтобы отклонить что-либо, если Параметр включает любые опасные ключевые слова или разделители:
Здесь x может быть table1.col1, table1.col4, table2.col1
IF LOCATE('DROP', x) > 0 OR LOCATE('INSERT', x) > 0 OR LOCATE('UPDATE', x) > 0
OR LOCATE(';', x) > 0 OR LOCATE('DELETE', x) > 0 THEN
Я упустил что-то большое? Или, может быть, есть готовый способ сделать это в MySQL?
Функция MySQL PREPARE не может обрабатывать несколько операторов SQL, поэтому вектор внедрения с точкой с запятой (;) не поможет злоумышленнику. sqlfiddle.com/#!9/5b8011
Спасибо, ребята, очень полезно, я знал о словах внутри слов, которые могут быть заблокированы, у меня был INSERT с пробелом в какой-то момент, и я беспокоился, что вам не всегда нужен пробел после INSERT, но, насколько я понимаю, единственное, что должно быть включено, - это имена полей / таблиц, которые я определяю, так что все должно быть в порядке. Полезно знать, что ; тоже не нужен.






Не существует "готового" способа, но регулярные выражения упростят ваш код:
where x regexp 'DROP|INSERT|UPDATE|;|DELETE'
Я не уверен, что это действительно то, что вам нужно. Он найдет PREINSERTION и DELETING. Но это проще и равносильно вашей логике.
Я приму это как принятый ответ, поскольку он состоит из одной строки, и я могу легко добавить еще несколько предупреждающих слов, если это необходимо.
Что, если x равно
table1.dateINSERTion? Ваш тест определит его местонахождение ... Лучше (но далеко не идеально) вставить такой пробел, как этотIF LOCATE('INSERT ', x) > 0