mysql (i) _real_escape_string, на что можно положиться?

function Query() { $args = func_get_args (); if (sizeof ($args) > 0) { $query = $args[0]; for ($i = 1; $i < sizeof ($args); $i++) $query = preg_replace ("/\?/", "'" . mysql_real_escape_string ($args[$i]) . "'", $query, 1); } else { return FALSE; } 

У меня есть такая функция. В основном, я делаю запрос следующим образом:

 $this->Query('SELECT * FROM USERS WHERE Username = ? AND Points < ?', $username, $points); 

В настоящее время он поддерживает устаревшие функции mysql , но адаптация к mysqli будет такой же простой, как замена mysql на mysqli в моем классе.

Является ли это безопасным подходом к атакам SQL Injection? Каждый вопросительный знак автоматически mysql_real_escape_string и у меня никогда не было проблем, но следует ли использовать mysqli_real_escape_string для дезинфекции?

Я знаю о подготовленных bindParam mysqli, но использование bindParam для каждой переменной кажется мне немного переполненным.

Как вы думаете?

Сегодня действительно замечательный день – вторая хорошая попытка создать разумный уровень абстракции базы данных в строке.

Должен ли я использовать mysqli_real_escape_string для дезинфекции?

Неа.
Просто потому, что эта функция не дезинфицирует ничего.

Но для форматирования строковых литералов SQL эта функция является обязательной и ее нельзя избежать или заменить.
Таким образом, вы правильно используете эту функцию, форматируя только строки и форматируя их безоговорочно .
Итак, у вас есть вопросы, абсолютно безопасные , если вы можете использовать? знак, чтобы заменить фактические данные (и – чтобы даже nitpick жаловался в режиме ожидания – до тех пор, пока вы устанавливаете кодировку SQL с помощью функции mysql(i)_set_charset() ).

Если кто-то называет ваш подход сломанным – попросите у них полный фрагмент кода-доказательства, чтобы показать определенную уязвимость.

Однако позвольте мне обратить ваше внимание на пару важных вещей.

  1. Динамические части запроса SQL не ограничиваются только строками. Например, эти 2 запроса не будут работать с вашей функцией:

     SELECT * FROM table LIMIT ?,? SELECT * FROM table ORDER BY ? 

    просто потому, что номера и идентификаторы требуют различного форматирования.
    Таким образом, лучше использовать тип-намеки , чтобы указать вашу функцию, какой формат применять

  2. Выполнение запроса – это только часть задания. Вам также нужно получить результаты. Почему бы не получить их уже, без раздувания кода с ненужными вызовами?
  3. Должен быть способ вставить литерал? помещает в запрос без их разбора.

Пожалуйста, взгляните на мой класс , который построен по тому же принципу, что и ваш, но с улучшениями, о которых я говорил выше. Надеюсь, вы сочтете это полезным или, по крайней мере, стоит одолжить идею или две.

Использование привязанных параметров не является избыточным и должно быть необходимо. Он будет более эффективно избегать и готовить ваши параметры.

 $stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)"); mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent); $code = 'DEU'; $language = 'Bavarian'; $official = "F"; $percent = 11.2; /* execute prepared statement */ mysqli_stmt_execute($stmt); 

Это действительно похоже на излишний?

Документация

если вы используете mysqli вместо mysql. Было бы лучше использовать mysqli_real_escape_string. Остерегайтесь того, что порядок параметров был изменен. (% и _ все еще не экранированы)