Mysqli_real_escape_string уязвим - PullRequest
0 голосов
/ 07 июня 2018

Так что я был занят PHP, вставляя данные в mysql, когда хотел знать: я наткнулся на некоторые посты, в которых говорится, что использование одинарных кавычек для вставки данных в базу данных - это плохая практика.один из примеров: Почему VALUES записываются между кавычками при отправке в базу данных? В посте рассказывается о том, почему они пишутся между кавычками, но ясно было одно: вставлять это как:1003 *

$sql = INSERT INTO example (example1, example2, example3) VALUES 
('$example1', '$example2', '$example3');

Почему это плохая практика?По-видимому, он уязвим для инъекций, как указано в приведенной выше ссылке.ОП его вопрос был связан с комментарием: мы используем mysqli_real_escape_string для этого.Ответ был таким:

@ XX В значительной степени да, это альтернативное решение проблемы.Он ничего не отключает, но экранирует вещи, например, «становится» или «» в строке SQL, не давая злоумышленнику завершить строку.Есть неловкие случаи, когда такое экранирование сложно, и легко пропустить один экранирующий вызов среди многих, поэтому параметризованные запросы считаются наиболее надежным подходом.

Прежде всего: как работает скриптхотите обмануть mysqli_real_escape_string, чтобы НЕ убегать от определенных вещей?Я нашел что-то, что говорит следующее, и поправьте меня, если я ошибаюсь: mysqli_real_escape_string - пример 100% безопасности .Как видите, он ссылается на другую страницу, на которую есть ответ.Однако затем он заявляет, что его данные должны быть на 100% безопасными, а кто-то другой отвечает:

Да, это в целом безопасно.Mysql и mysqli совершенно безопасны при правильном использовании (несмотря на определенные ошибки в очень специфических кодировках).Преимущество подготовленных заявлений состоит в том, что труднее делать неправильные вещи.

У меня есть следующий пример, чтобы прояснить для себя: у меня 2 двери, 1 дверь открыта, но сзадизакрытая дверь.Как бы вы атаковали открытую дверь с закрытой дверью перед ней?

Здесь есть ответ: SQL-инъекция, которая обходит mysql_real_escape_string () , но он говорит в качестве безопасного примера:

mysql_query('SET NAMES utf8');
$var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");`

Разве mysqli_real_escape_string уже не делает то же самое?он просто указывает, какие символы должны быть mysqli_real_escaped_string.Так как же это может внезапно стать безопасным?Так как он делает то же самое, что и когда вы говорите:

$example = mysqli_real_escape_string ($conn, $_POST['exampleVariable']);

Так как это:

mysql_query('SET NAMES utf8');
$var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");

станет безопасным и это:

$example = mysqli_real_escape_string ($conn, $_POST['exampleVariable']);

не?Разве он не сужает то, что mysqli_real_escape_string может избежать, что делает его более уязвимым?

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Дело в том, что mysqli_real_escape_string () или другое правильное экранирование на самом деле технически безопасно, в конце концов, это то же самое, что и параметризованные запросы.Тем не менее, всегда есть, однако.Например, это безопасно только если у вас есть кавычки вокруг переменных.Без кавычек это не так.Когда это 1000-строчный проект с одним разработчиком, это, вероятно, нормально в первые 3 месяца.Тогда, в конце концов, даже этот один разработчик забудет цитаты, потому что они не всегда нужны синтаксически.Представьте, что произойдет в проекте с 2 миллионами LOC с 200 разработчиками через 5 лет.

Аналогично, вы никогда не должны забывать об использовании функции ручного выхода.Это может быть легко в первую очередь.Затем есть переменная, которая проверена и может содержать только число, так что вы уверены, что можно просто вставить ее без экранирования.Затем вы передумали и превратили его в строку, потому что запрос все равно в порядке.Или кто-то еще делает это через 2 года.И так далее.Это не техническая проблема.Это проблема управления, в долгосрочной перспективе ваш код каким-то образом будет уязвим.Следовательно, это плохая практика.

Еще один момент, гораздо сложнее автоматически сканировать уязвимости SQL-инъекций, если выполняется ручное экранирование.Сканеры статического кода могут легко найти все экземпляры составных запросов, но им очень сложно сопоставить предыдущее экранирование, если оно есть.Если вы используете что-то вроде параметризованных запросов, найти инъекции sql просто, потому что все конкатенации являются потенциальными кандидатами.

0 голосов
/ 07 июня 2018

Установка набора символов для соединения не меняет то, что mysqli_real_escape_string() экранирует.Но он избегает ошибки многобайтовых символов, поскольку контролирует интерпретацию строки после вставки escape-символов обратной косой черты.

Конечно, вы можете избежать любой неопределенности с помощью , используя вместо этого параметры запроса .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...