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

Когда использовать filter_input()

Этот вопрос был первоначально задан в комментарии здесь.

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

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

4b9b3361

Ответ 1

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

Я считаю, что вы всегда должны использовать его (или расширение filter в целом). Для этого есть как минимум 3 причины:

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

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

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

Ответ 2

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

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

Требуется ли filter_input(), если вы используете параметризованные запросы и htmlspecialchars(), прежде чем печатать какие-либо данные, предоставленные пользователем?

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


Функция filter_input имеет много полезных фильтров, и я использую некоторые из них (то есть FILTER_VALIDATE_EMAIL). проверить фильтры полезны для проверки ввода. Однако IMO, те, которые преобразуют данные, должны использоваться только на выходе.

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

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

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

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

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

Вы также можете прочитать Почему escape-on-input - это плохая идея. Вот некоторые отрывки, с которыми я согласен, на всякий случай, когда статья исчезает [акцент в оригинале].

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

и

По умолчанию вы портили свои данные. Система [...] теперь лежит о том, какие данные пришли.

и

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

и

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

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


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

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

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

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

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

Резюме

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

  • использовать проверить фильтры на входе
  • использовать дезинфицировать фильтры на выходе
  • запомнить TIMTOWDI - Например, Я предпочитаю htmlspecialchars() (у которого больше опций) по FILTER_SANITIZE_FULL_SPECIAL_CHARS или FILTER_SANITIZE_SPECIAL_CHARS (что ускоряет разрывы строк)