Мне кажется ненужным, но мне всегда говорили "Filter Input, Escape Output". Итак, помимо базы данных (или другой формы хранения), есть ли необходимость фильтровать введенные данные?
Ответ 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 (что ускоряет разрывы строк)