Когда следует использовать подготовленные заявления?

Первоначально я использовал 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