Волшебные кавычки в PHP
В соответствии с руководство по PHP, чтобы сделать код более переносимым, они рекомендуют использовать что-то вроде следующего для экранирования данных:
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
У меня есть другие проверки проверки, которые я буду выполнять, но насколько безопасно это строго в плане выхода из данных? Я также видел, что магические кавычки будут устаревать в PHP 6. Как это повлияет на вышеуказанный код? Я бы предпочел не полагаться на функцию экранирования, специфичную для базы данных, такую как mysql_real_escape_string().
Ответы
Ответ 1
Магические цитаты по своей сути нарушены. Они предназначались для дезинфекции ввода в сценарий PHP, но, не зная, как этот ввод будет использоваться, невозможно провести правильную дезинфекцию. Во всяком случае, вам лучше проверить, включены ли магические кавычки, затем вызвать stripslashes() в $ _GET/$ _ POST/$ _ COOKIES/$ _ REQUEST, а затем санировать переменные в той точке, где вы их где-то используете. Например, urlencode(), если вы используете его в URL, htmlentities(), если вы печатаете его обратно на веб-страницу, или используйте функцию экранирования драйвера базы данных, если вы сохраняете ее в базе данных. Обратите внимание, что эти входные массивы могут содержать вложенные массивы, поэтому вам может потребоваться написать функцию, которая может возвращаться в вложенные массивы, чтобы убрать и эти слэши.
Справочная страница PHP по магическим кавычкам соглашается:
"Эта функция УСТАРЕЛА с PHP 5.3.0 и УДАЛЕНА с PHP 5.4.0. Использование этой функции крайне нежелательно. Magic Quotes - это процесс, который автоматически экранирует входящие данные в сценарий PHP. Предпочитается кодировать с помощью magic отключать кавычки и вместо этого экранировать данные во время выполнения по мере необходимости. "
Ответ 2
Волшебные кавычки были ошибкой дизайна. Их использование несовместимо с сохранением вашего здравомыслия.
Я предпочитаю:
if (get_magic_quotes_gpc()) {
throw new Exception("Turn magic quotes off now!");
}
Не записывайте код для совместимости с нарушенными настройками. Вместо этого защитите их использование, указав свой код FAIL FAST.
Ответ 3
Я использую следующий код в файле заголовка моего веб-сайта, чтобы отменить эффекты magic_quotes:
<?php
// Strips slashes recursively only up to 3 levels to prevent attackers from
// causing a Qaru error.
function stripslashes_array(&$array, $iterations=0) {
if ($iterations < 3) {
foreach ($array as $key => $value) {
if (is_array($value)) {
stripslashes_array($array[$key], $iterations + 1);
} else {
$array[$key] = stripslashes($array[$key]);
}
}
}
}
if (get_magic_quotes_gpc()) {
stripslashes_array($_GET);
stripslashes_array($_POST);
stripslashes_array($_COOKIE);
}
?>
Затем я могу написать остальную часть моего кода, как будто magic_quotes никогда не существовало.
Ответ 4
"Я бы предпочел не полагаться на функцию escaping для конкретной базы данных, такую как mysql_real_escape_string()"
Затем используйте что-то вроде PDO. Но вы все равно должны отменить ущерб, нанесенный магическими кавычками.
Ответ 5
Поместите требование PHP 5.2 или выше в свой код и используйте фильтр API. Функции filter_*
напрямую обрабатывают необработанные входные данные (они никогда не касаются $_POST
и т.д.), Поэтому они не подвержены влиянию magic_quotes_gpc
.
Затем этот пример:
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
Может стать следующим:
$lastname = filter_input(INPUT_POST, 'lastname');
Ответ 6
Правильно, это не лучший способ сделать это, а не самый безопасный. Побег лучше всего делать по отношению к тому, за что вы ускользаете. Если он хранится в базе данных mysql, используйте mysql_real_escape_string, который учитывает другие локали, наборы символов. Для HTML, htmlentities. Для использования в коде escapeshellcmd, escapeshellarg. Да, вам, вероятно, сначала нужно нажать на мешалки, если будут включены магические цитаты. Но лучше не рассчитывать на это или использовать его.
Ответ 7
Относительно использования функции экранирования, специфичной для базы данных, вам в значительной степени нужно. Я нашел просто использование addslashes()
для отказа в редких случаях с MySQL. Вы можете написать функцию escape, которая определяет, какой DB вы используете, а затем использовать approriate escape-функцию.
Ответ 8
Вы можете попробовать следующее:
if (get_magic_quotes_gpc()) {
$_REQUEST = array_map('stripslashes', $_REQUEST);
$_GET = array_map('stripslashes', $_GET);
$_POST = array_map('stripslashes', $_POST);
$_GET = array_map('stripslashes', $_COOKIES);
}
Ответ 9
"Я бы предпочел не полагаться на функцию escaping для конкретной базы данных, такую как mysql_real_escape_string()"
Также addlashes можно обмануть, а также проверить этот пост:
http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string
Ответ 10
Ваш пример кода обратный, вы должны сделать следующее:
if (get_magic_quotes_gpc()) {
$lastname = stripslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
Обратите внимание, что это оставляет ваши входные данные в "сыром" состоянии точно так же, как пользователь набрал его - никаких дополнительных обратных косых черт и потенциально загруженных атаками SQL Injection и XSRF - и это именно то, что вы хотите. Затем убедитесь, что вы всегда используете одно из следующих действий:
- Когда
echo
введите переменную в HTML, оберните ее в htmlentities()
- При размещении в mysql используйте подготовленные операторы или еще
mysql_real_escape_string()
как минимум.
- Когда
echo
введите переменную в код Javascritpt, используйте json_encode()
У Джоэла Спольского есть хороший совет по началу работы в Неверный код неправильного кода
Ответ 11
Просто нашел это на страницах руководства PHP, выглядит как довольно умный способ разделить их (имеет дело с ключами и значениями)..):
if (get_magic_quotes_gpc())
{
$_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true);
$_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true);
$_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true);
$_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true);
ini_set('magic_quotes_gpc', 0);
}
Ответ 12
Подготовленные утверждения PDO и Mysqli - лучший способ предотвратить SQL-инъекцию.
Но если вы переносите устаревший код, основанный на Magic Quotes для каждого SQL-запроса, вы можете ссылаться на yidas/php-magic-quotes для реализации Волшебные цитаты в среде с PHP 5.4 выше версии.
https://github.com/yidas/php-magic-quotes