Почему filter_input () является неполным? - PullRequest
12 голосов
/ 27 ноября 2009

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

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

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, может пролить свет на это.

Ответы [ 3 ]

8 голосов
/ 27 ноября 2009

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

Да, как это мило. Это не может быть сделано. Это не так, как работает обработка текста.

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

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

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

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

4 голосов
/ 27 ноября 2009

«входная фильтрация» или «очистка» - абсурдная идея. Держись от этого подальше.

Пояснения и дальнейшее обсуждение

Какой самый лучший метод для очистки ввода пользователя с помощью PHP?

Что еще я должен сделать, чтобы очистить ввод данных пользователем?

3 голосов
/ 27 ноября 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...