Магические кавычки в PHP
по словам руководство по PHP, чтобы сделать код более портативным, они рекомендуют использовать что-то вроде следующего для экранирования данных:
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
У меня есть другие проверки проверки, которые я буду выполнять, но насколько безопасно выше строго с точки зрения экранирования данных? Я также видел, что магические кавычки будут устаревшими в PHP 6. Как это повлияет на приведенный выше код? Я бы предпочел не полагаться на специфичную для базы данных функцию экранирования, такую как использования mysql_real_escape_string().
12 ответов
магические кавычки по своей сути сломаны. Они были предназначены для очистки ввода в php-скрипт, но без знания того, как этот ввод будет использоваться, невозможно правильно санировать. Во всяком случае, вам лучше проверить, включены ли магические кавычки, а затем вызвать stripslashes() на $_GET/$_POST/$_COOKIES/$_REQUEST, а затем санировать ваши переменные в точке, где вы его используете. Е. Г. функция urlencode() если вы используете его в URL-адрес, функция htmlentities (), если вы печатаете его обратно в веб страница или использование функции экранирования драйвера базы данных, если вы храните ее в базе данных. Обратите внимание, что эти входные массивы могут содержать суб-массивы, поэтому вам может потребоваться написать функцию, которая может рекурсировать в суб-массивы, чтобы очистить эти косые черты.
PHP man-страница на magic quotes согласен:
" эта функция устарела как PHP 5.3.0 и удалены с PHP 6.0.0. Опираясь на эту функцию крайне не рекомендуется. Magic Quotes-это процесс что автоматически ускользает входящие данные в php-скрипт. Это предпочтительный код с магическими кавычками и вместо того, чтобы избежать данных по время выполнения, по мере необходимости."
Magic quotes были ошибкой дизайна. Их применение несовместимо с retainnig вашей вменяемости.
Я предпочитаю:
if (get_magic_quotes_gpc()) {
throw new Exception("Turn magic quotes off now!");
}
Не пишите код для совместимости с изначально сломанными настройками. Вместо этого защитите aginst их использование, имея свой код СБОЙ БЫСТРО.
Я использую следующий код в заголовочном файле моего сайта, чтобы отменить эффекты magic_quotes:
<?php
// Strips slashes recursively only up to 3 levels to prevent attackers from
// causing a stack overflow 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 никогда не существовал.
" Я бы предпочел не полагаться на специфичную для базы данных экранирующую функцию, такую как mysql_real_escape_string ()"
тогда используйте что-то вроде PDO. Но вы все равно должны отменить урон, нанесенный волшебными цитатами.
поместите требование PHP 5.2 или выше в свой код и используйте фильтр API. The filter_*
функции получают доступ к необработанным входным данным напрямую (они никогда не касаются $_POST
etc.) таким образом, они полностью не затронуты magic_quotes_gpc
.
тогда этот пример:
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
может стать этот:
$lastname = filter_input(INPUT_POST, 'lastname');
правильно, это не лучший способ сделать это и не самый безопасный. Бегство лучше всего делать по отношению к тому, ради чего вы убегаете. Если он должен храниться в базе данных mysql, используйте mysql_real_escape_string, который учитывает другие локали, наборы символов. Для HTML, htmlentities. Для использования в коде, escapeshellcmd, escapeshellarg. Да, вы, вероятно, нужно stirpslashes первых, если магические кавычки на. Но лучше не рассчитывать на это и не использовать.
Что касается использования конкретной функции экранирования базы данных, вам в значительной степени нужно. Я нашел только использование addslashes()
для сбоя в редких случаях с MySQL. Вы можете написать функцию escape, которая определяет, какую БД вы используете, а затем использовать функцию approriate escape.
вы можете попробовать это:
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);
}
" Я бы предпочел не полагаться на специфичную для базы данных экранирующую функцию, такую как mysql_real_escape_string ()"
также addslashes можно обмануть, а также проверить этот пост:
http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string
ваш пример кода назад, вы должны делать следующее:
if (get_magic_quotes_gpc()) {
$lastname = stripslashes($_POST['lastname']);
} else {
$lastname = $_POST['lastname'];
}
обратите внимание, что это оставляет ваши входные данные в "сыром" состоянии точно так же, как пользователь набрал его - никаких дополнительных обратных косых черт и потенциально загруженных SQL - инъекций и XSRF-атак-и это именно то, что вы хотите. Тогда вы убедитесь, что вы всегда используйте одно из следующих действий:
- , когда
echo
ing переменной в HTML, оберните его вhtmlentities()
- когда помещая его в mysql, используйте подготовленные операторы или еще
mysql_real_escape_string()
как минимум. - , когда
echo
ing переменной в код Javascritpt, используйтеjson_encode()
у Джоэла Спольски есть хороший стартовый совет в Неправильный Код Выглядит Неправильно
только что нашел это на руководство по 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);
}
подготовил заявления PDO и Mysqli лучший способ предотвратить SQL-инъекции.
но если вы переносите устаревший код, который основан на волшебных кавычках для каждого SQL-запроса, вы можете ссылаться yidas / php-magic-котировки для реализации магических кавычек в среде с PHP 5.4 выше версии.