2013-02-27 2 views
25

Этот вопрос изначально был задан в комментарии here.Когда использовать filter_input()

Нужно ли filter_input(), если вы используете параметризованные запросы и htmlspecialchars() перед печатью любых предоставленных пользователем данных?

Мне кажется ненужным для меня, но мне всегда говорили «Filter Input, Escape Output». Итак, помимо базы данных (или другой формы хранения), есть ли необходимость фильтровать введенные данные?

+2

Для нормализации формата в любом случае. Это избыточно для предотвращения XSS и SQL-эксплойтов, если вы уже используете контекст для запросов и вывода. Не мешает иметь фактические/проверенные адреса электронной почты, URL-адреса или обычный текст, где они принадлежат. – mario

+0

@mario Можете ли вы объяснить немного больше, что вы подразумеваете под «форматирование-нормализация»? – Jonathan

ответ

27

Ну, будут разные мнения.

Я считаю, что вы всегда должны использовать его (или, вообще, расширение filter). Существует по меньшей мере 3 причины:

  1. Санитарный вход - это то, что вы всегда должны делать. Поскольку функция дает вам эту возможность, на самом деле нет причин искать другие способы дезинфекции ввода. Поскольку это расширение, фильтр также будет намного быстрее и, скорее всего, более безопасным, чем большинство PHP-решений, что, безусловно, не повредит. Единственное исключение - если вам нужен более специализированный фильтр. Даже тогда вы должны захватить значение, используя фильтр FILTER_UNSAFE_RAW (см. № 3).

  2. Есть много положительных героев в расширении filter. Это может сэкономить вам часы от написания кода санитарии и проверки. Конечно, он не охватывает каждый отдельный случай, но этого достаточно, чтобы вы могли больше сосредоточиться на конкретном файле фильтрации/проверки.

  3. Использование этой функции очень хорошо, когда вы отлаживаете или проверяете свой код. Когда функция используется, вы точно знаете, какой будет вход. Например, если вы используете фильтр FILTER_SANITIZE_NUMBER_INT, вы можете быть уверены, что на входе будет число - нет SQL-инъекций, HTML или код Javascript и т. Д. Если вы, с другой стороны, используете что-то вроде FILTER_UNSAFE_RAW, тогда вы знаете что к ней следует относиться осторожно и что это может легко вызвать проблемы безопасности.

+0

Хотя я надеялся на несколько мнений (ответов) на этот вопрос, ваш ответ очень ясен и имеет большой смысл. Благодаря! – Jonathan

+0

Это не конкретизировано и примеров нет. Почему это хорошо, что может пойти не так? Это был вопрос, и этот ответ не подходит. –

23

Как говорит Сверри М. Олсен, на этом есть разные мнения.

Я очень согласен с философией Вход фильтра, выход выхода.

Действительно ли filter_input() по-прежнему необходим, если вы используете параметризованные запросы и htmlspecialchars() перед печатью любых предоставленных пользователем данных?

Короткий ответ: IMO, Нет, это не обязательно, но может быть полезно в некоторых случаях.


filter_input функция имеет много полезных фильтров, и я использую некоторые из них (т.е. FILTER_VALIDATE_EMAIL). validate filters полезны для validation input. Тем не менее, ИМО, те, которые преобразуют данные, должны использоваться только на выходе.

Некоторые люди поощряют выход из строя.Действительно, примеры, приведенные на странице руководства filter_input, как представляется, также способствуют этому.

$search_html = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_SPECIAL_CHARS); 
$search_url = filter_input(INPUT_GET, 'search', FILTER_SANITIZE_ENCODED); 

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

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

Например, Google Analytics обрабатывает ввод таким способом, который заставляет мои кодированные амперсанды (% 26) декодироваться до исключения параметров запроса. В результате у меня есть статистика для параметров запроса, которые на самом деле даже не существуют в моих URL-адресах. См. my question относительно этой проблемы, которая остается нерешенной.

Вы также можете прочитать Why escape-on-input is a bad idea. Вот некоторые отрывки, с которыми я согласен, на всякий случай статья исчезает [акцент в оригинале].

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

и

Вы испортили данные по умолчанию. Система [...] лежит теперь о том, что данные приходят.

и

на вход утечке не только не иметь дело с проблемами больше, чем один выход, он будет на самом деле сделать ваши данные неверным для многих выходов.

и

PHP используется, чтобы иметь возможность, называемую волшебные кавычки. Это была функция escape-on-input, которая [...] вызвала всевозможные проблемы. [...] Согласно Лердорфу, гораздо более новое расширение «фильтра» PHP - «magic_quotes done right». Но он по-прежнему страдает почти всеми описанными здесь проблемами.

Так как это фильтра расширения лучше, чем волшебные кавычки (кроме того, что он имеет много различных фильтров)? Фильтры вызывают многие из тех же проблем, что и магические цитаты.


Вот правила кодирования, которые я использую:

  • значения в $ _POST, $ _GET, $ _REQUEST и т.д., не должны быть экранированы и всегда следует считать небезопасными
  • значения должны быть подтверждены перед тем, как быть записаны в базу данных или сохранены в $ _SESSION
  • значения, ожидаемые как числовые или логические, должны быть дезинфицированы перед записью в базу данных или храниться в $ _SESSION
  • доверия, числовые и логические значения из базы данных и $ _SESSION действительно числовые или логические
  • строковых значений должны быть SQL маскирования перед использованием непосредственно в любом SQL запросе (не строковые значения должны быть продезинфицировать) или использовать подготовленные заявления
  • строковых значений должны быть HTML-маскирование перед использованием в выходном HTML (не строковые значения должны быть продезинфицировать)
  • строковых значения должны быть закодированным процентом перед использованием в строках запроса (нестроковые значения должны быть продезинфицировать)
  • использовать переменное именование (например, * _url, * _html, * _sql) для хранения преобразованных данных

Терминология

для моих здесь, вот как я определяю термины, используемые выше.

  1. для проверки средств для подтверждения каких-либо предположений делается о данных, таких как имеющие определенный формат или поля, имеющие значение
  2. дезинфицировать средства для подтверждения значения точно, как и ожидалось (т.е. $ ID_NUM должен не содержат ничего, кроме цифр)

Резюме

В целом (там могут быть некоторые исключения), я бы порекомендовал следующее:

  • использование validate filters на вход
  • использование sanitize filters на выходе
  • запомнить TIMTOWDI - Например, Я предпочитаю htmlspecialchars() (который имеет больше возможностей) над FILTER_SANITIZE_FULL_SPECIAL_CHARS или FILTER_SANITIZE_SPECIAL_CHARS (который избегает разрывов строк)
+0

Я провожу так много времени, читая это, и нахожу только один пример о специфике google api. Спасибо за ответ, но вопрос был «ПОЧЕМУ», и этот ответ не отвечает. –

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