2009-11-27 2 views
10

В настоящий момент я много работаю над CMS на основе PHP, и пока я нахожусь на этом, я хотел бы переместить всю обработку и санитарию ввода пользователя в одно центральное место. (На данный момент здесь $ _REQUEST, здесь $ _GET и т. Д.).Почему filter_input() неполный?

Мне очень нравится filter_input() и хотел бы использовать его для базовой санитарии, но неясно, действительно ли эта функция готова к производству. Например, documentation называет следующие параметры для $ типа

INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV, INPUT_SESSION (not implemented yet) and INPUT_REQUEST (not implemented yet).

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

Возможно, кто-то, знакомый с процессом разработки PHP, может пролить свет на это.

+1

и в 2015 году до сих пор, кажется, не быть никакой реализации за $ _SESSION, по крайней мере не проверил другие пока им только собирание PHP мяч снова, но filter_var - это работа. – Chris

+2

'INPUT_SESSION' и' INPUT_FILES' не реализованы (хотя '$ _FILES' представляет многомерный вариант использования и по умолчанию не похож на остальных). Используйте 'filter_var_array()' для '$ _SESSION'. Я также могу отметить, что нет «INPUT_DATABASE», но у вас все еще есть обязанности. Снова попробуйте 'filter_var_array()'. –

ответ

8

Я хотел бы, чтобы переместить всю обработку и санацию пользовательского ввода в одном месте

Да, как хорошо, что будет. Это невозможно. Это не то, как работает текстовая обработка.

Если вы вставляете текст из одного контекста в другой, вам нужно использовать правильные экраны. (mysql_real_escape_string для строковых литералов MySQL, htmlspecialchars для содержимого HTML, urlencode для параметров URL, другие для конкретных контекстов). В начале вашего скрипта, когда вы фильтруете, вы не знаете, где ваш вход будет завершен, поэтому вы не знаете, как его избежать.

Возможно, что одна входная строка перемещается как в базу данных (должна быть экранирована SQL), так и непосредственно на страницу (должна быть скрыта HTML). Никого не избежать, которое охватывает оба этих случая. Вы можете использовать оба escapes один за другим, но тогда значение в HTML будет иметь странные обратные косые черты, появляющиеся в нем, и копия в базе данных будет заполнена амперсандами. Несколько раундов этого неправильного кодирования, и вы получаете ту ситуацию, когда каждый раз, когда вы что-то редактируете, выходят длинные строки \\\\\\\\\\\\\\\\\\\\ и &.

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

Таким образом, вы можете убежать только на лету, когда один тип текста переходит в другой. Лучшая стратегия, чтобы избежать проблемы, заключается в том, чтобы избежать конкатенации текста в другие контексты настолько, насколько это возможно, например, с помощью параметризованных запросов вместо построения строки SQL и определения функции echo(htmlspecialchars()) с красивым коротким именем, чтобы сделать это меньше работы для ввода или использования альтернативной системы шаблонов, которая по умолчанию удаляет HTML-файлы.

+0

Вы пишете ужасно длинные ответы (хотя хорошее объяснение). –

+0

@bobince: Я говорю, что это можно сделать до степени, если вы 1.) знаете, что вам нужно в сценарии, и 2.) отметьте измененные параметры как то, что они есть. У меня была моя доля в \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ :) Моя основная цель - иметь одну базовую «контрольную точку безопасности» с определенным набором проверок, вместо того, чтобы вытаскивать материал из массивов по всему коду. –

+0

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

3

При программировании вы должны быть как можно более ограничительными на своем входе. Это относится и к источникам данных. $ _REQUEST содержит все в $ _GET, $ _POST и $ _COOKIE, что может привести к проблемам.

Подумайте, например, что произойдет, если плагин вашей CMS вводит новый специальный ключ в один из них, который существует как значимый ключ в другом плагине?

Так что никогда не используйте $ _REQUEST. Используйте $ _GET, $ _POST или $ _COOKIE, в зависимости от вашего сценария. Это хорошая практика быть как можно более строгой, и это не имеет ничего общего с PHP, но с программированием в целом.

+1

Действительная точка для $ _REQUEST, но тогда они должны сказать это, а не оставлять ее нереализованной. –

Смежные вопросы