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

Что не так с использованием $_REQUEST []?

Я видел несколько сообщений, в которых говорилось, что не использовать переменную $_REQUEST. Обычно я этого не делаю, но иногда это удобно. Что с ним не так?

4b9b3361

Ответ 1

Абсолютно ничего плохого в том, что можно вводить данные как из $_GET, так и $_POST. Фактически это то, что вы почти всегда хотите делать:

  • для простого идемпотентного запроса, обычно передаваемого через GET, существует вероятность того, что объем требуемых данных не будет соответствовать URL-адресу, поэтому вместо этого он будет изменен на запрос POST.

  • для запроса, который имеет реальный эффект, вы должны проверить, что он отправлен методом POST. Но способ сделать это - явно проверить $_SERVER['REQUEST_METHOD'], а не полагаться на $_POST пустым для GET. И вообще, если метод POST, вы все равно захотите взять некоторые параметры запроса из URL.

Нет, проблема с $_REQUEST не связана с объединением параметров GET и POST. Это также, по умолчанию, включает $_COOKIE. И файлы cookie действительно не похожи на параметры отправки формы: вы почти никогда не хотите относиться к ним как к одной и той же вещи.

Если вы случайно набрали cookie на своем сайте с тем же именем, что и один из ваших параметров формы, тогда формы, которые полагаются на этот параметр, будут таинственно перестать работать должным образом из-за значений cookie, переопределяющих ожидаемые параметры. Это очень легко сделать, если у вас несколько приложений на одном и том же сайте, и их очень сложно отладить, когда у вас есть только несколько пользователей со старыми кукисами, которые вы больше не используете и не разбиваете формы, - еще один может воспроизвести.

Вы можете изменить это поведение на гораздо более разумный GP (no C) порядок с помощью request_order в PHP 5.3. Если это невозможно, я лично избегал $_REQUEST и, если бы мне нужен объединенный массив GET + POST, создайте его вручную.

Ответ 2

Я просматривал некоторые сообщения в новостных группах на PHP Internals и нашел интересную дискуссию по этой теме. Первоначальный поток был о чем-то другом, но замечание Stefan Esser, эксперта по безопасности (в случае отсутствия) в мире PHP, превратило дискуссию в соответствие с последствиями безопасности использования $_REQUEST для нескольких сообщений.

Цитирование Стефан Эссер на внутренних языках PHP

$_ REQUEST - одна из самых больших недостатков дизайна в PHP. Каждое приложение, использующее $_REQUEST, скорее всего, уязвим для запроса на задержку кросс-сайта Проблемы с подделкой. (Это в основном означает, что, например, файл cookie с именем (age) существует, он всегда будет перезаписывать контент GET/POST и, следовательно, будут выполняться нежелательные запросы)

и в позже ответьте на тот же поток

Дело не в том, что кто-то может подделать GET, POST; COOKIE. Речь идет о том, что COOKIE будут перезаписывать данные GET и POST в ЗАПРОС.

Поэтому я мог заразить ваш браузер куки файлом, который говорит, например. action = logout, и с этого дня вы не можете использовать приложение потому что REQUEST [action] будет выходить навсегда (пока вы не вручную удалите файл cookie).

И заразить вас COOKIE так просто...
a) Я мог бы использовать XSS в любом приложении на субдомене
б) Когда-либо пробовал устанавливать cookie для *.co.uk или *.co.kr, когда вы владеете один домен?
c) Другой кросс-домен любым способом...

И если вы считаете, что это не проблема, я могу сказать вам, что есть простая возможность установить f.e. a *.co.kr cookie, результаты которого в нескольких версиях PHP, просто возвращающих белые страницы. Представьте себе: всего один куки файл, чтобы убить все страницы PHP в *.co.kr

И установив незаконный идентификатор сеанса в файле cookie, действительном для *.co.kr, в переменная, называемая + PHPSESSID = незаконная, вы все еще можете использовать DOS для каждого PHP приложение в корее, используя сеансы PHP...

Обсуждение продолжается еще несколько сообщений и интересно читать.


Как вы можете видеть, основная проблема с $_REQUEST заключается не столько в том, что у нее есть данные от $_GET и $_POST, но и от $_COOKIE. Некоторые другие ребята из списка предложили изменить порядок, в котором заполняется $_REQUEST, например. сначала заполняя его $_COOKIE, но это может привести к многочисленным другим потенциальным проблемам, например, при обработке сеанса.

Вы можете полностью исключить $_COOKIES из глобального $_REQUEST, так что он не будет перезаписан никаким другим массивом (на самом деле вы можете ограничить его любой комбинацией его стандартного содержимого, например Руководство по настройке переменной variable_order в руководстве:

variable_order Устанавливает порядок разбора переменных EGPCS (среда, Get, Post, Cookie и Server). Например, если для параметра variable_order установлено значение "SP", тогда PHP создаст суперглобалы $_SERVER и $_POST, но не создаст $_ENV, $_GET и $_COOKIE. Установка на "" означает, что суперглобалы не будут установлены.

Но опять же, вы можете также не использовать $_REQUEST вообще, просто потому, что в PHP вы можете получить доступ к среде, Get, Post, Cookie и Server в своих глобальных комбинациях и меньше иметь один вектор атаки. Вы все еще должны дезинфицировать эти данные, но об этом меньше всего беспокоиться.


Теперь вы можете задаться вопросом, почему $_REQUEST существует и почему он не удаляется. Это было задано также и для PHP Internals. Ссылаясь на Расмуса Лердорфа о Почему существует $_REQUEST? в PHP Internals

Чем больше таких вещей мы удалим, тем труднее для людей быстро перейти к более новым, более быстрым и более безопасным версиям PHP. Что вызывает больше разочарования для всех, чем несколько "уродливых" наследников функции. Если есть приличная техническая причина, производительность или безопасности, тогда нам нужно внимательно рассмотреть это. В этом случае вещь, на которую мы должны смотреть, - это не нужно ли нам удалять $_REQUEST но следует ли удалять с него данные cookie. Множество конфигураций уже делают это, включая все мои собственные, и существует сильная действительная причина безопасности для исключения файлов cookie в $_REQUEST. Большинство людей используют $_REQUEST означает GET или POST, не понимая, что он может также содержать печенье, и как таковые плохие парни могут потенциально сделать некоторые инъекции печенья трюки и безупречные приложения.

В любом случае, надеюсь, что пролить свет.

Ответ 3

$_REQUEST относится ко всем типам запросов (GET, POST и т.д.). Иногда это полезно, но обычно лучше указать точный метод ($ _GET, $_POST и т.д.).

Ответ 4

Запросы GET должны быть идемпотентными, а запросы POST обычно отсутствуют. Это означает, что данные в $_GET и $_POST обычно должны использоваться по-разному.

Если ваше приложение использует данные из $_REQUEST, оно будет вести себя одинаково для запросов GET и POST, что нарушает идемпотентность GET.

Ответ 5

$_REQUEST, как правило, считается вредным по той же причине, что преобразования данных с простой и средней степенью сложности часто выполняются в коде приложения, а не в SQL: некоторые программисты сосут.

Как таковой, если каждый имеет тенденцию использовать $_REQUEST всюду, я могу делать что-либо через GET, который мог бы через POST, что означает настройку тегов <img> на моем (вредоносном) сайте, которые заставляют пользователей войти в ваш e- коммерческий модуль, чтобы покупать продукты тихо, или я могу заставить их щелкнуть ссылки, которые приведут к опасным действиям или выявлению конфиденциальной информации (возможно, для меня).

Однако это из-за новичка или, по крайней мере, неопытного программиста PHP, делающего простые ошибки. Во-первых, знайте, когда данные о том, какой тип подходит. Например, у меня есть веб-служба, которая может возвращать ответы в URLEncoding, XML или JSON. Приложение решает, как отформатировать ответ, проверяя заголовок HTTP_ACCEPT, но может быть принудительно принудительно введено в один, отправив параметр format.

При проверке содержимого параметра формата он может быть отправлен через querystring или postdata, в зависимости от множества факторов, не в последнюю очередь из которых является то, хотят ли вызывающие приложения "& format = json" mixed с его просьбой. В этом случае $_REQUEST очень удобно, потому что это позволяет мне ввести что-то вроде этого:

$format = isset($_POST['format']) ? $_POST['format'] 
    : (isset($_GET['format']) ? $_GET['format'] : null);

Я больше не буду болтать дальше, но достаточно сказать, что использование $_REQUEST не отговаривается, потому что оно по своей сути опасно - это просто еще один инструмент, который делает именно то, о чем его спрашивают, понимаете ли вы эти последствия или нет - это плохое, ленивое или неосведомленное решение плохого, ленивого или неопытного программиста, вызывающего эту проблему.

Безопасное использование $_REQUEST


  • Знайте свои данные. У вас должно быть какое-то ожидание относительно того, какие данные вы получите, поэтому выполните санитарию. Данные для базы данных? addslashes() или *_escape_string(). Собираетесь показать его пользователю? htmlentities() или htmlspecialchars(). Ожидайте числовые данные? is_numeric() или ctype_digit(). Фактически filter_input(), и связанные с ним функции предназначены для того, чтобы ничего не делать, кроме проверки и дезинфекции данных. Всегда используйте эти инструменты.
  • Не следует напрямую обращаться к данным суперглобальных данных, поставляемым пользователем. Создавайте привычку каждый день очищать свои данные и перемещать данные для очистки переменных, даже если это просто $post_clean. Альтернативно, вы можете просто очистить непосредственно в суперглобалях, но причина, по которой я защищаю использование отдельной переменной, заключается в том, что это позволяет легко обнаруживать уязвимости в коде, поскольку что-либо указывает прямо на суперглобал, а не на санированный эквивалент считается опасной ошибкой.
  • Знайте, откуда должны поступать данные. Ссылаясь на мой пример выше, вполне разумно разрешить отправку переменной формата ответа через GET или POST. Я также разрешаю передавать переменную "действие" с помощью любого метода. Однако сами действия имеют очень специфические требования относительно приемлемого HTTP-глагола. Функции, например, которые вносят изменения в данные, используемые службой, могут быть отправлены только через POST. Запросы для определенных типов данных, не связанных с низкой или низкой привилегией (например, динамически сгенерированные изображения карт), могут подаваться в ответ на запросы любого из этих методов.

В заключение запомните это простое правило:

БЕЗОПАСНОСТЬ - ЧТО ВЫ СДЕЛАЛИ ЭТО, ЛЮДИ!

EDIT:

Я сильно рекомендую совет bobince: если можно, установите параметр request_order в php.ini на "GP"; то есть никакого компонента cookie. В 98% случаев случаев почти нет рациональных аргументов, поскольку данные cookie почти никогда не считаются сравнимыми с запросами или postdata.

P.S., Anecdote!

Я знал программиста, который думал о $_REQUEST месте просто хранить данные, которые были доступны суперглобальным способом. Важные имена пользователей и пароли, пути к файлам, вы называете это, и он хранился в $_REQUEST. Он был немного удивлен (хотя и не комично, к сожалению), когда я рассказал ему, как ведет себя эта переменная. Разумеется, эта практика была свергнута.

Ответ 6

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

Ответ 7

Мне нравится использовать его. Это дает вам гибкость в использовании GET или POST, которые могут пригодиться для таких вещей, как формы поиска, где большая часть данных времени POSTED, но иногда вам нужно указать ссылку на конкретный поиск, так что вы можете использовать параметры GET вместо.

Кроме того, если вы посмотрите на многие другие языки (например, ASP.NET), они не делают различий между GET и POST-переменными вообще.

ETA:

Я никогда не использовал REQUEST, чтобы получить значения COOKIE, но я думаю, что Kyle Butt делает замечание в комментариях к этому сообщению об этом. Не рекомендуется использовать REQUEST для получения значений COOKIE. Я считаю, что он прав, что есть реальный потенциал для подделки подделок, если вы это делаете.

Кроме того, порядок загрузки материала в REQUEST контролируется параметрами конфигурации в php.ini(variables_order и request_order). Итак, если у вас есть одна и та же переменная, переданная через POST и GET, которая фактически попадает в REQUEST, зависит от этих настроек ini. Это может повлиять на переносимость, если вы зависите от конкретного заказа, и эти настройки настроены иначе, чем вы ожидаете.

Ответ 8

Единственное время, использующее $_REQUEST, не является плохой идеей с GET.

  • Если вы используете его для загрузки значений POST, вы рискуете использовать поддельные запросы подделок
  • Если вы используете его для загрузки значений файлов cookie, вы снова рискуете подделки подделок.

И даже с GET, $_GET короче, чем $_REQUEST;)

Ответ 9

Важно понимать, когда использовать POST, когда использовать GET и когда использовать cookie. С $_REQUEST ценность, которую вы ищете, могла бы исходить от любого из них. Если вы ожидаете получить значение от POST или GET или от COOKIE, это более информативно для кого-то, читающего ваш код, для использования конкретной переменной вместо $_REQUEST.

Кто-то еще указал на то, что вы не хотите, чтобы все POST или файлы cookie были переопределены GET, потому что для всех из них существуют разные правила кросс-сайта, например, если вы возвращаете данные ajax при использовании $_REQUEST, вы уязвимы для атаки через сайт script.

Ответ 10

Я мог бы использоваться только в том случае, если вы хотите получить текущий URL-адрес или имя хоста, но для фактического анализа данных с этого URL-адреса, таких как парметеры с использованием символа и символа, это, вероятно, не очень хорошая идея. В общем, вы не хотите использовать неопределенное описание того, что вы пытаетесь сделать. Если вам нужно указать, что где $_REQUEST плохо, если вам не нужно быть конкретным, тогда не стесняйтесь использовать его. Я бы подумал.

Ответ 11

Если вы знаете, какие данные вы хотите, вы должны явно спросить об этом. IMO, GET и POST - это два разных животных, и я не могу думать о хорошей причине, почему вам когда-либо понадобилось бы смешивать почтовые данные и строки запросов. Если у кого-то есть, мне было бы интересно.

Удобно использовать $_REQUEST, когда ваши сценарии могут отвечать на GET или POST таким же образом. Я бы сказал, однако, что это должен быть крайне редкий случай, и в большинстве случаев предпочтительными являются две отдельные функции для обработки двух отдельных понятий или, по крайней мере, проверки метода и выбора правильных переменных. Поток программ обычно намного проще отслеживать, когда нет необходимости перекрестно ссылаться на переменные. Будьте добры к человеку, который должен поддерживать ваш код через 6 месяцев. Это может быть вы.

В дополнение к проблемам безопасности и WTF, вызванным переменными cookie и средой в переменной REQUEST (не заставляйте меня начинать с GLOBAL), подумайте о том, что может произойти в будущем, если PHP начнет изначально поддерживать другие методы, такие как PUT и УДАЛИТЬ. Хотя крайне маловероятно, что они будут объединены в суперклассу REQUEST, возможно, они могут быть включены как опция в настройку variable_order. Таким образом, вы действительно не знаете, что такое REQUEST, и что имеет приоритет, особенно если ваш код развернут на стороннем сервере.

Является ли POST более безопасным, чем GET? На самом деле, нет. Лучше использовать GET там, где это возможно, потому что в ваших журналах легче видеть, как ваше приложение используется при атаке. POST лучше для операций, которые влияют на состояние домена, потому что пауки обычно не следуют за ними, а прогностические механизмы отбора не удаляют весь ваш контент при входе в вашу CMS. Однако речь шла не о достоинствах GET и POST, а о том, как получатель должен обрабатывать входящие данные и почему это плохо для их слияния, так что это действительно просто BTW.

Ответ 12

Я думаю, что нет проблемы с $_REQUEST, но мы должны быть осторожны при ее использовании, поскольку это набор переменных из трех источников (GPC).

Я думаю, $_REQUEST по-прежнему доступен, чтобы старые программы были совместимы с новыми версиями php, но если мы начнем новые проекты (включая новые библиотеки), я думаю, нам больше не следует использовать $_REQUEST, чтобы сделать программы более четкими. Мы должны даже рассмотреть возможность удаления использования $_REQUEST и замены его на функцию-обертку, чтобы сделать программу более легкой, особенно при обработке больших представленных текстовых данных, поскольку $_REQUEST содержит копии $_POST.

// delete $_REQUEST when program execute, the program would be lighter 
// when large text submitted
unset($_REQUEST);

// wrapper function to get request var
function GetRequest($key, $default = null, $source = '') 
{
  if ($source == 'get') {
    if (isset($_GET[$key])) { 
      return $_GET[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'post') {
    if (isset($_POST[$key])) { 
      return $_POST[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'cookie') {
    if (isset($_COOKIE[$key])) { 
      return $_COOKIE[$key]; 
    } else { 
      return $default; 
    }
  } else {
    // no source specified, then find in GPC
    if (isset($_GET[$key])) {
      return $_GET[$key];     
    } else if (isset($_POST[$key])) {
      return $_POST[$key]; 
    } else if (isset($_COOKIE[$key])) {
      return $_COOKIE[$key]; 
    } else {
      return $default; 
    } 
  }
}

Ответ 13

Darren Cook: "Начиная с php 5.3, по умолчанию php.ini говорит, что только данные GET и POST помещаются в $_REQUEST. См. php.net/request_order Я просто наткнулся на этот разрыв обратной совместимости при ожидании файла cookie данные находятся в $_REQUEST и задаются вопросом, почему он не работает!"

Вау... просто некоторые из моих скриптов перестали работать из-за обновления до PHP 5.3. То же самое: предположим, что файлы cookie будут установлены при использовании переменной $_REQUEST. С обновлением, которое прекратило работать.

Теперь я вызываю значения cookie отдельно с помощью $_COOKIE["Cookie_name"]...

Ответ 14

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

В PHP 7 вы можете сделать это:

$request = array_merge($_GET ?? [], $_POST ?? []);

Это позволяет избежать проблемы с cookie и в худшем случае дает пустой массив, а в лучшем случае слияние $ _GET и $ _POST, причем последний имеет приоритет. Если вы не слишком обеспокоены разрешением вставки URL параметров через строку запроса, это довольно удобно.

Ответ 15

Это очень неуверенно. Также неудобно, так как вы не знаете, получаете ли вы POST или GET или другой запрос. Вы действительно должны знать разницу между ними при разработке своих приложений. GET очень небезопасен, так как он прошел в URL-адресе и не подходит ни к чему, кроме навигации по страницам. POST, хотя и не безопасен сам по себе, обеспечивает один уровень безопасности.