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

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

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

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

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

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

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

Solutions Collecting From Web of "Как безопасно создавать переменные PHP с извлечением"

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

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

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

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

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

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

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

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

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

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

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

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

Что нужно использовать простой foreach вместо extract ():

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

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

Его опасный для использования экстракт в глобальном масштабе и для _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 } }