Правильное слияние с MySQLI | запрос по подготовленным операторам

Я прочитал:

поможет вам НЕ против инъекций. Beause escaping – это просто средство форматирования строк, а не превентор для инъекций любыми способами. Идите фигуру. Тем не менее, экранирование имеет что-то общее с подготовленными заявлениями: они оба не гарантируют вас от инъекций, если вы используете его только против пресловутого «пользовательского ввода», а не как строгое правило для построения ЛЮБОГО запроса, несмотря на источник данных. если вам нужно вставить не данные, а идентификатор или ключевое слово.

В следующей статье: Являются ли динамические запросы mysql с sql-экранированием столь же безопасными, как подготовленные операторы?

Поэтому мой вопрос заключается в том, что использование:

$Var = "UserInput Data Possible SQL Injection"; $mysqli->real_escape_string($Var); 

не обеспечивает защиту от SQL Injection?

Я хочу использовать $mysqli->query(); поэтому я могу использовать fetch_array(MYSQLI_ASSOC); Потому что, если быть откровенным, я не знаю, как получить результаты в виде массива после использования prepared оператора.

Итак, если у меня это в моем соединении с базой данных:

 $STD = new mysqli('localhost', 'root', 'xx', 'xx'); $STD->set_charset('utf8'); if ($STD->connect_error) { die("Standard Access Has Been Revoked. Please Contact Administration"); }elseif (!$STD){ die ("Other problem With Connecting To Database, Please Contact Administration"); } 

как указано в руководстве для real_escape_string

http://php.net/manual/en/mysqli.real-escape-string.php

Вышеуказанные списки:

Предостережение Безопасность: набор символов по умолчанию Набор символов должен быть установлен либо на уровне сервера, либо с помощью функции API mysqli_set_charset (), чтобы он влиял на mysqli_real_escape_string (). Дополнительную информацию см. В разделе «Концепции» на наборах символов.

Какие ссылки ссылаются на: http://php.net/manual/en/mysqli.set-charset.php


Мой общий вопрос может быть разделен на три варианта: первый будет запрашивать fetch_array() equlivant для prepared операторов, что обеспечит полное предотвращение внедрения SQL из-за подготовленных операторов, отправляющих данные как необработанные.


Первый вопрос в этом формате:

Я использую Query как:

 $GetCompletedQuery = $STD->query("SELECT Status FROM UserCompletion WHERE `UserID`=' ". $STD->real_escape_string($_SESSION['UID']) ."'"); $GetCompletedArray = $GetCompletedQuery->fetch_array(MYSQLI_ASSOC); 

Что возвращает:

Массив ([Status] => 1)

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

 $GetCompletedQuery = $STD->prepare("SELECT Status FROM UserCompletion WHERE `UserID`=?"); $GetCompletedQuery->bind_param('i', $_SESSION['UID']); $GetCompletedQuery->execute(); $GetCompletedArray = $GetCompletedQuery->fetch_row; print_r($GetCompletedArray); 

Что возвращает:

Неустранимая ошибка: вызовите функцию-член fetch_row () для не-объекта в /var/www/New/API/Constants.php в строке 17

То же самое появляется, когда я пытаюсь fetch_array() который, как я знаю, не может использоваться с подготовленными операторами.

Итак, каков будет вариант использования подготовленных заявлений?


Второй вопрос

Если я использую свой обычный запрос как:

 $GetCompletedQuery = $STD->query("SELECT Status FROM UserCompletion WHERE `UserID`=' ". $STD->real_escape_string($_SESSION['UID']) ."'"); 

что позволило мне использовать fetch_array(); правильно ли защищены данные SQL-инъекции?


Третий вопрос:

Должен ли я избегать / защищать от SQL-инъекции для $_SESSION['UID']; поскольку это назначается в следующей усадьбе:

 $InnerJoinQuery = $STD->query(" SELECT Users.ID, Users.Username, Users.Password, UserInformation.LastName, UserInformation.Firstname, UserInformation.DOB FROM Users INNER JOIN UserInformation ON Users.ID = UserInformation.UserID WHERE Users.Username = '".$_SESSION['real_name']."'"); $InnerJoinArray = $InnerJoinQuery->fetch_array(MYSQLI_ASSOC); $_SESSION['UID'] = $InnerJoinArray['ID']; $_SESSION['Password'] = $InnerJoinArray['Password']; $_SESSION['Firstname'] = $InnerJoinArray['Firstname']; $_SESSION['LastName'] = $InnerJoinArray['LastName']; $_SESSION['DOB'] = $InnerJoinArray['DOB']; 

Этот фрагмент объяснил:

Пользователь регистрируется с именем пользователя и паролем, файл получает информацию из базы данных на основе $_SESSION['real_name']; и добавляет массив $ _SESSION к результатам, добавляя их в другой ключ.

Вопрос для этого фрагмента должен я даже избегать / защищать от SQL-инъекции, когда $_SESSION['UID']; назначается через базу данных на основе $_SESSION['real_name'];

Благодарю за то, что ты читал этот массивный кусок.

  1. http://php.net/manual/en/mysqli-stmt.get-result.php
  2. Да, но это очень плохая практика:
    • это поможет вам в этом случае, но только в этом случае и обманет что-нибудь еще
    • ручное экранирование просто глупо, лучше пусть водитель сделает это за вас
  3. ДА, потому что нет такой вещи, как SQL-инъекция, но неправильное форматирование ТОЛЬКО

заключается в использовании $mysqli->real_escape_string($Var); не обеспечивает защиту от SQL Injection?

Я не передумал: уверен, это не так.
Это будет сделано только в том случае, если вы заключите результирующее значение в кавычки (и установите правильную кодировку, используя mysqli_set_charset() чтобы быть строгим).

Слушайте, SQL-инъекция не является чем-то существенным, существующим на ее собственном, но это скорее всего следствие. Следствием неверно отформатированного запроса.
При создании запроса вы должны правильно форматировать каждую его часть. Не из-за какой-то «инъекции», а ради нее. Когда вы собираетесь вставлять строку в запрос, вы должны положить ее в кавычки или получить синтаксическую ошибку. Когда вы собираетесь вставить строку в запрос, вам нужно избегать этих кавычек, используемых для разграничения этой строки, или вы получите синтаксическую ошибку. И так далее. Это правильное форматирование, которое должно вас беспокоить, а не пугающие рассказы о инъекции. И пока у вас есть каждая динамическая часть запроса, правильно отформатированная в соответствии с ее типом – никакая инъекция никогда не была бы возможна

Таким образом, источником переменной или ее ценности никогда не должно быть вашей заботы. Но только это место в запросе:

  • строки должны быть заключены в кавычки и сбрасывать эти кавычки.
  • числа должны быть приведены к типу.
  • идентификаторы должны быть заключены в обратные выходы и удлинены эти обратные

Когда идет статическая часть запроса, жестко закодированная в скрипте, мы не используем такие строгие стандарты – скажем, мы не включаем каждый идентификатор в backticks.
Но когда дело идет о динамической части запроса, применение правил форматирования должно быть строгим правилом, поскольку мы не можем точно знать переменный контент.

Кстати, есть еще один способ отформатировать ваши строки и числа – подготовленные заявления. Это не так удобно, как должно быть, но поскольку он использует заполнители для представления ваших данных в запросе, рекомендуется использовать более глупые ручные форматирования.