Риск безопасности?$ _REQUEST переменные ... $$ в локальном стеке - PullRequest
2 голосов
/ 21 октября 2010

Я разговаривал с одним из моих программистов ранее, и он показал мне кусок кода, который он рассматривал:

foreach($_REQUEST as $var=>$val) {
    $$var = addslashes($val);
}

Он хотел иметь возможность использовать $varName вместо того, чтобы писать $_REQUEST['varName']

Я посоветовал ему использовать mysql_real_escape_string вместо addSlashes и не помещать переменные $_REQUEST в локальный стек, потому что это дает хакерам вектор присоединения. Мне кажется, это та же проблема, что и у старой директивы REGISTER_GLOBALS.

Он сказал, что угрозы безопасности не были одинаковыми, поскольку все эти переменные создавались в локальном стеке. Поэтому я был неуверен и проверил страницу переменных PHP в: http://www.php.net/manual/en/language.variables.variable.php, но не увидел ссылки на суперглобальные переменные и безопасность, кроме окна предупреждения.

Могут ли хакеры легко воспользоваться этой конструкцией?

Ответы [ 5 ]

2 голосов
/ 21 октября 2010

Это похоже на возвращение 6 лет улучшений безопасности PHP ... По сути, register_globals и magic_quotes вместе взятые! Эти два помечены как устаревшие в последних версиях PHP и будут удалены из будущих версий по очень веским причинам.

Представьте себе следующий код:

if ($is_admin) {
    do_administrative_task();
}

Теперь кто-то делает следующий запрос:

http://www.example.com/script.php?is_admin=1

И просто так, вы администратор!

Аналогично, addslashes() на самом деле не обеспечивает никакой защиты от атак SQL-инъекций, потому что не понимает современные наборы символов. Смехотворно легко создать что-то, что обойдёт addslashes() и завалит вашу базу данных.

2 голосов
/ 21 октября 2010

Я не кодировал php годами, но разве нет функции, которая делает это?Возможно, называется extract ?

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

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

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

И ров addslashes().Это не только неправильное место для экранирования входящих данных, но и неправильная функция.

0 голосов
/ 22 октября 2010

Прямо так!Как рассматриваемый программист, на самом деле есть три отдельные проблемы:

  1. То, что $_REQUEST не более небезопасно, чем $_GET или $_POST, учитывая, что по умолчанию PHP $_COOKIES имеет приоритет над $_GET и $_POST.
  2. Установка значения суперглобала более безопасна, чем локальная переменная в функции или локальная переменная метода объекта.
  3. Конечная пользовательская переменная в функции доступна глобально.

Давайте начнем с вершины.

  1. $_POST и $_GET не более безопасны, чем $_REQUEST.Вся информация, полученная из формы, является грязной.Период.Несмотря на.Если я могу отправить поддельные куки, я знаю, как подделать POST переменные.Аргумент спорный.
  2. Итак, мы берем локальную переменную, которую создаем с помощью $var. Область действия этой переменной находится только внутри функции / метода.Защищает ли содержимое суперглобала значение предоставленных пользователем данных более безопасно, чем локальная переменная, которая очищается при очистке стека функции / метода?Интересно ...
  3. Давайте возьмем фрагмент

function some_function() {
   foreach($_POST as $var=>$val) {
        $$var = $val; 
  }
}

Теперь, если $_POST содержит переменную с именем _POST, этот код будет установленлокальная переменная $_POST, содержащая значение.Однако суперглобальные переменные переопределят это, и любая ссылка на $_POST будет ссылаться на суперглобальную, а не на локальную переменную, и поэтому локальная $_POST не может быть использована.Учитывая эту функциональность PHP, без использования глобального ключевого слова обычно невозможно полностью переопределить суперглобальный

0 голосов
/ 21 октября 2010

Да. Если URL-адрес запроса содержит ...&GLOBALS[var]=1, он перезапишет соответствующую глобальную переменную.

Он должен по крайней мере рассмотреть следующую конструкцию для безопасности:

 extract($_REQUEST, EXTR_PREFIX_ALL, "var_");  // or EXTR_SKIP

Это даст локализованным переменным хотя бы префикс и предотвратит перезапись глобальных переменных. Для хорошей меры также используйте array_map("addslashes", $_REQUEST) или более подходящую функцию экранирования. Но на самом деле, это просто magic_quotes под другим именем. (Offtopic: попробуйте отключить mysql_query и использовать PDO и подготовленные операторы, что проще и безопаснее.)

...