Вы можете подумать, что использование «экранирующей» функции, такой как mysqli :: real_escape_string () на каждом входе, так же безопасно, как и использование подготовленных операторов.
За исключением:
Экранирование не работает для числовых входов, только строки в кавычках и даты в кавычках.
Экранирование имеет некоторые неожиданные случаи, когда оно не работает. Это крайние случаи, но они существуют. См. Несколько примеров в ответах на SQL-инъекцию, которая обходит mysql_real_escape_string ()
Экранирование сложнее при написании кода. Делать это правильно, отнимает много времени и дотошно, и легко ошибиться. Разработчики часто испытывают искушение пропустить это.
Разработчики, которые заботятся о предотвращении внедрения SQL-кода, рекомендуют использовать параметры запроса вместо этого по нескольким причинам, включая, но не ограничиваясь следующим:
Параметры запроса также работают для числовых значений.
Код, использующий параметры запроса, легче писать и читать, и менее подвержен ошибкам. Мы ожидаем, что, как только у них появится привычка использовать параметры запроса, разработчики будут использовать этот метод более надежно, и поэтому уязвимости будут менее вероятными.
Например, вы можете написать код, подобный следующему:
$sql = "INSERT INTO mytable (col1, col2, col3, col4, col5, col6)
VALUES ('" . mysqli_real_escape_string($_POST['col1']) . "', "
. $mysqli->real_escape_string($_POST['col2']) . "', '"
. $mysqli->real_escape_string($_POST['col3']) . "', '"
. $mysqli->real_escape_string($_POST['col4']) . ", '"
. $mysqli->real_escape_string($_POST['col5']) . "', '"
. $mysqli->real_escape_string($_POST['col6']) . "')";
Можете ли вы заметить ошибки? С достаточным количеством времени я уверен, что вы можете. Но это замедлит ваше кодирование и может привести к потере зрения при поиске пропущенных символов кавычек и других ошибок.
Но это гораздо проще написать, а потом легче прочитать:
$sql = "INSERT INTO mytable (col1, col2, col3, col4, col5, col6)
VALUES (?, ?, ?, ?, ?, ?)";
Параметры запросов безопасны для большего количества типов данных и помогают быстрее писать код с меньшим количеством ошибок. Это большой выигрыш.
Как и другие комментарии выше, я не согласен с вашим утверждением, что MySQLi не поддерживает параметры запроса. Это ясно показано в документации: https://www.php.net/manual/en/mysqli.prepare.php
Если у вас есть какой-либо код-обертка, который использует MySQLi, но не поддерживает mysqli::prepare()
, тогда я рекомендую вам прекратить использовать этот код-обертку. Либо напишите функции для своего фреймворка, чтобы он использовал параметры запроса, либо получите другой фреймворк.
Также отвечает как "изменить" ваш фреймворк или НЕ подходит!
Послушайте, вот правда: если вы не можете написать код, который безопасно обрабатывает пользовательский ввод, вы не должны принимать пользовательский ввод.
Вы предполагаете, что есть способы использования preg_replace()
, но это не так. т. Существует так много способов внедрения кода (SQL или Javascript), что в конечном итоге вы также отфильтруете множество законных комментариев пользователей. Как отреагируют ваши пользователи, если ваше веб-приложение уберет кавычки иапострофы из их комментариев? Какие еще символы вам нужно вырезать?
Параметры запроса являются наиболее эффективным решением этой проблемы. Ваше сопротивление им абсурдно.
Это похоже на электрика, которыйспрашивает: «Как я могу предотвратить шок? Но я не могу использовать утепленные перчатки или инструменты, поэтому не советую этого делать. "