Магические кавычки в 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-атак-и это именно то, что вы хотите. Тогда вы убедитесь, что вы всегда используйте одно из следующих действий:

  • , когда echoing переменной в HTML, оберните его в htmlentities()
  • когда помещая его в mysql, используйте подготовленные операторы или еще mysql_real_escape_string() как минимум.
  • , когда echoing переменной в код 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 выше версии.

https://github.com/yidas/php-magic-quotes