Защита от инъекций PHP mysql


Я написал эту короткую функцию для защиты от внедрения my_sql, из-за ее важности я просто хочу перепроверить с другими, что это будет функционировать так, как я намереваюсь.

foreach($_REQUEST as $key => $value) {          
    $_REQUEST[$key] = stripslashes($value);
    $_REQUEST[$key] = mysql_real_escape_string($_REQUEST[$key]);
} 
Author: TMS, 2011-08-12

6 answers

Ну, вы используете stripslashes(), потому что magic_quotes_gpc задано? Таким образом, этот код будет работать только тогда, когда установлен magic_quotes_gpc! Я бы рекомендовал вам отключить его и не использовать вызов strislashes().

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

При цитировании вы всегда цитируете текст для какого-то конкретного вывода, например:

  1. строковое значение для запроса mysql
  2. like выражение для запроса mysql
  3. html-код
  4. json
  5. регулярное выражение mysql
  6. регулярное выражение php

Для каждого случая вам нужны разные цитаты, потому что каждое использование присутствует в разных синтаксических контекстах. Это также подразумевает, что цитирование должно выполняться не на входе в PHP, а на конкретном выходе! Именно по этой причине такие функции, как magic_quotes_gpc, не работают (всегда убедитесь, что они выключены!!!).

Итак, что методы, которые можно было бы использовать для цитирования в этих конкретных случаях? (Не стесняйтесь поправлять меня, возможно, есть более современные методы, но они работают для меня)

  1. mysql_real_escape_string($str)
  2. mysql_real_escape_string(addcslashes($str, "%_"))
  3. htmlspecialchars($str)
  4. json_encode() - только для utf8! Я использую свою функцию для iso-8859-2
  5. mysql_real_escape_string(addcslashes($str, '^.[]$()|*+?{}')) - вы не можете использовать preg_quote в этом случае, потому что обратная косая черта будет экранирована два раза!
  6. preg_quote()
 11
Author: TMS, 2011-08-12 16:38:55

Если вы используете PDO (правильно), вам не нужно беспокоиться о внедрении MySQL.

Пример:

/* Execute a prepared statement by passing an array of insert values */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->execute(array(':calories' => $calories, ':colour' => $colour));

Дополнительная информация

 5
Author: Arjan, 2011-08-12 16:40:22

Похоже на подход кувалды. Вам не нужно stripslashes, если только вы не используете magic_quotes. Литье по типу может быть более элегантным, когда вы знаете, что хотите int, float или bool.

Дополнительная информация:

Литье по типу: http://php.net/manual/en/language.types.type-juggling.php

Тестирование на магические кавычки: http://www.php.net/manual/en/function.get-magic-quotes-gpc.php (Спасибо Каролису)

 3
Author: Shad, 2011-08-12 19:54:04

Вам необходимо явно добавить идентификатор подключения к базе данных в

mysql_real_escape_string(..., $db_connection_identifier);

Строка Mysql_real_escape_string

Строка mysql_real_escape_string (строка $unescaped_string [, идентификатор ресурса $link_identifier])

 1
Author: ajreal, 2011-08-12 16:31:41

Если вы включаете произвольные $key в свой запрос, вам также следует избегать их.

 1
Author: Jared Ng, 2011-08-12 16:32:23

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

if (get_magic_quotes_gpc()) { // Check if magic quotes are enabled
    foreach($_REQUEST as $key => $value) {          
       $_REQUEST[$key] = stripslashes($value);
       $_REQUEST[$key] = stripslashes($_REQUEST[$key])
    } 
} else {
    foreach($_REQUEST as $key => $value) {
      $_REQUEST[$key] = mysql_real_escape_string($value);
      $_REQUEST[$key] = mysql_real_escape_string($_REQUEST[$key]);
    } 
}
 1
Author: Crakken, 2012-07-04 19:48:47