Когда следует использовать подготовленные заявления?
Первоначально я использовал mysql_connect
и mysql_query
, чтобы делать вещи. Затем я узнал о внедрении SQL, поэтому я пытаюсь научиться использовать подготовленные операторы. Я понимаю, как функции подготовки и выполнения класса PDO полезны для предотвращения внедрения SQL.
Нужны ли подготовленные операторы только тогда, когда пользовательский ввод хранится в базе данных? Было бы хорошо по-прежнему использовать mysql_num_rows
, поскольку я действительно не рискую быть взломанным с помощью этой функции? Или это более безопасно использовать подготовленные заявления для этого? Должен ли я использовать подготовленные операторы для всего, что связано с использованием MySQL? Почему?
Ответы
Ответ 1
TL/дг
Всегда. 100% времени, используйте его. Всегда; и даже если вам не нужно его использовать. ИСПОЛЬЗУЙТЕ ЕЩЕ ЕЩЕ.
mysql_*
функции устарели. ( Обратите внимание на большой красный квадрат?)
Предупреждение Это расширение было устарело в PHP 5.5.0, и оно было удалено в PHP 7.0.0. Вместо этого расширение MySQLi или PDO_MySQL должно быть используемый. См. Также MySQL: выбор руководства по API и связанные часто задаваемые вопросы для Больше Информация. Альтернативы этой функции включают:
Вам лучше использовать PDO
или MySQLi
. Любой из этих 2
будет достаточным в качестве совместимых библиотек при использовании подготовленных операторов.
Доверяя ввод пользователя без подготовленных инструкций/дезинфекции, это как оставить свой автомобиль в плохом районе, разблокирован и с ключами в замке зажигания. Вы в основном говорите, просто войдите и возьмите мои лакомства ![enter image description here]()
Вы должны никогда, и я имею в виду никогда, доверяйте пользователю ввод. Если вы этого не хотите:
![SQL Injection]()
В отношении данных и их хранения, как указано в комментариях, вы можете никогда и никогда не должны доверять каким-либо связанным с пользователем вводам. Если вы на 101% уверены, что данные, используемые для управления указанными базами данных/значениями, жестко закодированы в вашем приложении, вы должны использовать подготовленные инструкции.
Теперь о том, почему вы должны использовать подготовленные заявления. Это просто. Чтобы предотвратить SQL Injection, но самым прямым способом. Способ работы подготовленных операторов прост, он отправляет запрос и данные вместе, но отдельно (если это имеет смысл, ха-ха). Я имею в виду следующее:
Prepared Statements
Query: SELECT foo FROM bar WHERE foo = ?
Data: [? = 'a value here']
По сравнению со своим предшественником, где вы усекали запрос данными, отправляя его в целом - в свою очередь, это означает, что он был выполнен как одна транзакция, вызывающая уязвимости SQL Injection.
И вот пример псевдо PHP PDO
, чтобы показать вам простоту подготовленных операторов/привязок.
$dbh = PDO(....); // dsn in there mmm yeahh
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
Взято из руководства PHP для подготовленных заявлений PDO
Подробнее Чтение
Ответ 2
TL; DR Используйте подготовленные операторы в 100% случаев, если ваше приложение принимает любой пользовательский ввод
У вас, похоже, небольшая путаница. Сначала не используйте mysql_*
; функции mysql_*
устарели, устарели и небезопасны. Вместо этого используйте MySQLi
или PDO
. Во-вторых, mysql_num_rows
не имеет ничего общего с подготовленными операторами и вообще не является функцией PDO. Перед выполнением запроса вы готовите выражение, а не после него, когда хотите подсчитать строки.
Что касается того, когда готовить заявления, @Mike'Pomax'Kamermans пригвоздил его в комментариях. Если вы когда-либо, даже один раз, используете любые данные, которые когда-либо были затронуты пользователем - даже предположительно доверенным пользователем - или генерируются любым типом стороннего или стороннего приложения, включая браузер, с использованием подготовленных операторов. Только если 100% ваших данных жестко закодировано или сгенерировано полностью вашим кодом (например, простой переменной счетчика), вы можете доверять ему.
Например, вы не можете доверять:
- Usernames
- Пароли
- Адреса электронной почты
- Комментарии пользователей
- Телефонные номера
- Даты
- Строки поиска
- Строки клиента браузера
- Номера кредитных карт
- Имена файлов для загрузки
- И любой другой вид ввода, созданный пользователем или которым пользователь может манипулировать.
Вы должны проверить все (например, проверить, что адрес электронной почты действительно является адресом электронной почты), прежде чем помещать их в базу данных, конечно. Но даже тогда, используя подготовленные заявления, это безопасный путь.
Ответ 3
Mysql_*
уже устарел, поэтому лучше переключить mysqli_*
или PDO
Для предотвращения внедрения sql (mysql): - Как предотвратить SQL-инъекцию в PHP?.
И подготовленные операторы (это SQL-операторы, которые отправляются и анализируются сервером базы данных отдельно от любых параметров.) Используйте для каждого пользователя данные запроса.
например, при отправке данных, которые соответствуют/получают записи в db с запросом. так что при запуске запроса с данными формы.
Ответ 4
Для этого есть два решения:
01- Использовать подготовленные сообщения
Чтобы предотвратить инъекции SQL, нам нужно будет использовать что-то, называемое подготовленными операторами, которое использует связанные параметры. Подготовленные утверждения не объединяют переменные со строками SQL, поэтому злоумышленник не может изменять инструкцию SQL. Подготовленные выражения объединяют переменную с компилируемым оператором SQL, это означает, что SQL и переменные отправляются отдельно, а переменные интерпретируются как строки, а не часть оператора SQL.
02- Подготовленные выражения с mySQLi.
Используя методы, описанные ниже, вам не нужно использовать какие-либо другие методы фильтрации SQL-инъекций, такие как mysql_real_escape_string(). Это связано с тем, что с помощью подготовленных операторов невозможно выполнить обычную SQL-инъекцию.
eg -
$name = $_GET['username'];
if ($stmt = $mysqli->prepare("SELECT password FROM tbl_users WHERE name=?")) {
// Bind a variable to the parameter as a string.
$stmt->bind_param("s", $name);
// Execute the statement.
$stmt->execute();
// Get the variables from the query.
$stmt->bind_result($pass);
// Fetch the data.
$stmt->fetch();
// Display the data.
printf("Password for user %s is %s\n", $name, $pass);
// Close the prepared statement.
$stmt->close();
}
Вы можете найти более подробную информацию об этой форме - http://www.wikihow.com/Prevent-SQL-Injection-in-PHP