Защита от инъекций PHP mysql
Я написал эту короткую функцию для защиты от внедрения my_sql, из-за ее важности я просто хочу перепроверить с другими, что это будет функционировать так, как я намереваюсь.
foreach($_REQUEST as $key => $value) {
$_REQUEST[$key] = stripslashes($value);
$_REQUEST[$key] = mysql_real_escape_string($_REQUEST[$key]);
}
6 answers
Ну, вы используете stripslashes()
, потому что magic_quotes_gpc
задано? Таким образом, этот код будет работать только тогда, когда установлен magic_quotes_gpc
! Я бы рекомендовал вам отключить его и не использовать вызов strislashes().
Но обратите внимание, что нет ничего лучше "универсальной дезинфекции". Давайте назовем это просто цитированием , потому что в этом все дело.
При цитировании вы всегда цитируете текст для какого-то конкретного вывода, например:
- строковое значение для запроса mysql
-
like
выражение для запроса mysql - html-код
- json
- регулярное выражение mysql
- регулярное выражение php
Для каждого случая вам нужны разные цитаты, потому что каждое использование присутствует в разных синтаксических контекстах. Это также подразумевает, что цитирование должно выполняться не на входе в PHP, а на конкретном выходе! Именно по этой причине такие функции, как magic_quotes_gpc
, не работают (всегда убедитесь, что они выключены!!!).
Итак, что методы, которые можно было бы использовать для цитирования в этих конкретных случаях? (Не стесняйтесь поправлять меня, возможно, есть более современные методы, но они работают для меня)
mysql_real_escape_string($str)
mysql_real_escape_string(addcslashes($str, "%_"))
htmlspecialchars($str)
-
json_encode()
- только для utf8! Я использую свою функцию для iso-8859-2 -
mysql_real_escape_string(addcslashes($str, '^.[]$()|*+?{}'))
- вы не можете использовать preg_quote в этом случае, потому что обратная косая черта будет экранирована два раза! preg_quote()
Если вы используете 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));
Похоже на подход кувалды. Вам не нужно 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 (Спасибо Каролису)
Вам необходимо явно добавить идентификатор подключения к базе данных в
mysql_real_escape_string(..., $db_connection_identifier);
Строка Mysql_real_escape_string
Строка mysql_real_escape_string (строка $unescaped_string [, идентификатор ресурса $link_identifier])
Если вы включаете произвольные $key
в свой запрос, вам также следует избегать их.
Предложение Томаса хорошее, но вы всегда должны помнить о них обоих, так что это может быть здорово:
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]);
}
}