Подтвердить что ты не робот

Как безопасно создавать переменные PHP с извлечением

В моем предыдущем посте я спрашиваю, как создавать переменные из массива (Переменные PHP, сделанные с помощью foreach), у меня появилось несколько ответов, и я тестировал extract(), но я видели несколько против этого по соображениям безопасности.

Теперь мой вопрос заключается в том, как я могу использовать извлечение безопасным способом из $_POST, у которого есть массив, который был создан с использованием сериализации jquery.

С защищенным я имею в виду, что если пользователь вводит неверные данные, безопасный способ может позаботиться об этом без проблем.

У PHP-сайта есть небольшое предупреждение в команде extract:

Не использовать extract() на ненадежном данные, такие как пользовательский ввод (т.е. $_GET, $_FILES и т.д.). Если вы это сделаете, например если вы хотите запустить старый код, который опирается на register_globals временно, убедитесь, что вы используете один из непереписывая extract_type такие как EXTR_SKIP и быть в курсе что вы должны извлекать в том же порядок, определенный в variables_order внутри php.ini.

Он предупреждает об использовании, но не предоставляет пример, по крайней мере, того, как безопасно решить проблему пользователя извлечения.

4b9b3361

Ответ 1

Лучший вариант - не использовать extract() вообще. Это плохое дизайнерское решение со времен, когда PHP был эквивалентом влажной туалетной бумаги для написания защищенного кода.

Это может быть болезненно, но гораздо лучше записать длинную последовательность:

$var1 = $_POST['var1'];
$var2 = $_POST['var2'];
etc...

или просто используйте $_POST['var1'] и всю компанию в своем коде.

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

Ответ 2

Не используйте extract(), просто используйте foreach() в POST/GET, чтобы создать свой собственный массив/объект. extract() будет кошмаром для отладки, когда ваш код начнет увеличиваться.

Ответ 3

Это достаточно безопасно, если вы используете префикс, который не существует в других переменных:

extract($_POST, EXTR_PREFIX_ALL, 'unique_prefix');

Причина, по которой извлечение может быть опасной, аналогична использованию register_globals.

Ответ 4

Нет ничего плохого в extract, если вы используете его только для частичного извлечения известных входных переменных. Это не самый приятный синтаксис, но выполнимый с помощью:

extract(array_intersect_key($_POST,
        array_flip(array("var1", "var2", "var3", "var4"))));

Это сокращает возможные переменные $_POST и не будет извлекать неожиданные вещи. Общая выгода заключается в том, что вы все равно можете применить некоторую функцию фильтра, используя array_map. В некоторых настройках он уменьшает беспорядок кода по сравнению с индивидуальным копированием переменных.

Ответ 5

Как использовать простой foreach вместо extract():

foreach($_POST as $k => $v) $$k = $v;

Таким образом, вы можете добавить код безопасности в часть $$k = $v;.

Ответ 6

Его опасный для использования экстракт в глобальном масштабе и для _REQUEST, _GET, _POST, _COOKIE.

Однако, если вы разрешаете использовать только переменные, которые вы собираетесь использовать с помощью механизма фильтрации, и отключите все, что приходит извне, вы можете использовать извлечение.

Например, если вы напрямую загружаете _REQUEST, _GET, _POST, _COOKIE в функцию, которая будет делать extract() внутри и выпустить только те, которые вы определяете в return(), тогда вы тоже в безопасности. Поскольку все, что было извлечено, включая переменные от вредоносных попыток, останется внутри области функций и не сможет ничего сделать.

Итак, extract() уважает область действия - все, что вы извлекаете внутри функции, остается внутри этой функции, все, что вы извлекаете внутри метода класса, остается в рамках этого метода класса и не выходит нигде, не позволяя им.

Это означает, что в глобальном масштабе и в области функций/объектов вы можете безопасно использовать извлечение для доверенных данных.

Предполагая, что $args является ассоциативным массивом:


function funny($args)
{
  extract($args);

  // Hereon you can use the variables normally and they will stay in function scope

}

Ваши переменные останутся в пределах функции.

То же самое для метода класса:


class berserker
{
     public function funny($args)
     {
       extract($args);

       // Hereon you can use the variables normally and they will stay in method scope

     }

}