Волшебные кавычки в PHP - PullRequest
       83

Волшебные кавычки в PHP

16 голосов
/ 21 октября 2008

Согласно руководству по PHP , чтобы сделать код более переносимым, для экранирования данных рекомендуется использовать что-то вроде следующего:

if (!get_magic_quotes_gpc()) {
    $lastname = addslashes($_POST['lastname']);
} else {
    $lastname = $_POST['lastname'];
}

У меня есть другие проверочные проверки, которые я буду выполнять, но насколько безопасны вышеприведенные данные с точки зрения экранирования данных? Я также видел, что магические кавычки будут устаревшими в PHP 6. Как это повлияет на приведенный выше код? Я бы предпочел не полагаться на экранирующую функцию для конкретной базы данных, такую ​​как mysql_real_escape_string ().

Ответы [ 12 ]

25 голосов
/ 21 октября 2008

Магические кавычки по своей сути нарушены. Они предназначались для дезинфекции ввода в сценарий PHP, но, не зная, как этот ввод будет использоваться, невозможно провести правильную дезинфекцию. Во всяком случае, вам лучше проверить, включены ли магические кавычки, затем вызвать stripslashes () в $ _GET / $ _ POST / $ _ COOKIES / $ _ REQUEST, а затем санировать переменные в той точке, где вы их где-то используете. Например. urlencode (), если вы используете его в URL, htmlentities (), если вы печатаете его обратно на веб-страницу, или используйте функцию экранирования вашего драйвера базы данных, если вы храните его в базе данных. Обратите внимание, что эти входные массивы могут содержать вложенные массивы, поэтому вам может потребоваться написать функцию, которая может возвращаться в вложенные массивы, чтобы убрать и эти слэши.

Справочная страница PHP по магическим кавычкам согласна:

"Эта функция устарела как PHP 5.3.0 и УДАЛЕНО как PHP 5.4.0. Полагаться на эту функцию крайне не рекомендуется. Волшебные цитаты процесс, который автоматически уходит входящие данные в скрипт PHP. Это предпочтительнее кодировать магическими кавычками выключить и вместо этого избежать данных в время выполнения, по мере необходимости. "

17 голосов
/ 21 октября 2008

Магические кавычки были ошибкой дизайна. Их использование несовместимо с сохранением вашего здравомыслия.

Я предпочитаю:

if (get_magic_quotes_gpc()) {
   throw new Exception("Turn magic quotes off now!");
}

Не пишите код для совместимости с изначально нарушенными настройками. Вместо этого защищайте их использование, используя ваш код FAIL FAST .

6 голосов
/ 21 октября 2008

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

2 голосов
/ 14 января 2009

Установите в своем коде требование 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');
2 голосов
/ 21 октября 2008

"Я бы предпочел не полагаться на экранирующую функцию для конкретной базы данных, такую ​​как mysql_real_escape_string ()"

Затем используйте что-то вроде PDO . Но вы все равно должны обратить вспять урон, нанесенный магическими кавычками.

1 голос
/ 21 октября 2008

Правильно, это не лучший способ сделать это и не самый безопасный. Побег лучше всего делать в зависимости от того, за что вы бежите. Если это нужно хранить в базе данных mysql, используйте mysql_real_escape_string, которая учитывает другие локали, наборы символов. Для HTML htmlentities. Для использования в коде, escapeshellcmd, escapeshellarg. Да, вам, вероятно, нужно сначала использовать stirpslashes, если включены магические кавычки. Но лучше не рассчитывать на это или использовать его.

0 голосов
/ 04 июля 2017

Подготовленные операторы PDO и Mysqli являются лучшим способом предотвращения внедрения SQL.

Но если вы переносите устаревший код, основанный на магических кавычках для каждого SQL-запроса, вы можете обратиться yidas / php-magic-quotes для реализации магических кавычек в среде с PHP 5.4 выше версии .

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

0 голосов
/ 22 апреля 2010

Только что нашел это на страницах справки по 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);
}
0 голосов
/ 14 января 2009

Ваш пример кода задом наперед, вы должны сделать следующее:

if (get_magic_quotes_gpc()) {
  $lastname = stripslashes($_POST['lastname']);
} else {
  $lastname = $_POST['lastname'];
}

Обратите внимание, что это оставляет ваши входные данные в «сыром» состоянии в точности так, как их набрал пользователь - без дополнительной обратной косой черты и потенциальной загрузки с помощью SQL-инъекций и атак XSRF - и это именно то, что вам нужно. Затем убедитесь, что вы всегда используете одно из следующих действий:

  • Когда echo вставляет переменную в HTML, оберните ее в htmlentities()
  • При переводе в mysql используйте подготовленные операторы или как минимум mysql_real_escape_string().
  • Когда echo вводит переменную в код Javascritpt, используйте json_encode()

У Джоэла Спольски есть несколько хороших советов по началу работы: Создание неправильного кода выглядит неправильно

0 голосов
/ 14 января 2009

"Я бы предпочел не полагаться на экранирующую функцию для конкретной базы данных, такую ​​как mysql_real_escape_string ()"

Также можно обмануть аддеш, а также проверить этот пост:

http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

...