Когда фильтровать/дезинфицировать данные: перед вставкой базы данных или перед отображением?

Как я готов к решению проблемы фильтрации входных данных и дезинфекции, мне любопытно, есть ли лучшая (или наиболее используемая) практика? Лучше ли фильтровать/дезинфицировать данные (HTML, JavaScript и т.д.) Перед вставкой данных в базу данных или делать это, когда данные готовятся для отображения в HTML?

Несколько примечаний:

  • Я делаю это на PHP, но я подозреваю, что ответ на этот вопрос является агностиком языка. Но если у вас есть рекомендации, специфичные для PHP, пожалуйста, поделитесь!
  • Это не проблема экранирования данных для вставки базы данных. У меня уже есть обработка PDO, которая достаточно хорошо.

Спасибо!

Ответ 1

Когда дело доходит до отображения представленных пользователем данных, общепринятая мантра состоит в "Ввод фильтра, выход выхода".

Я бы порекомендовал вам избегать таких вещей, как html-сущности и т.д., прежде чем заходить в базу данных, потому что вы никогда не знаете, когда HTML не будет вашим средством отображения. Кроме того, для разных типов ситуаций требуются различные типы выходных экранов. Например, для встраивания строки в Javascript требуется другое экранирование, чем в HTML. Выполнение этого раньше может усыпить себя ложным чувством безопасности.

Итак, основное эмпирическое правило: дезинфицировать перед использованием и специально для этого использования; не упреждающе.

(Обратите внимание: я не говорю об экранировании вывода для SQL, просто для отображения. Пожалуйста, все равно выполняйте данные escape, привязанные к строке SQL).

Ответ 2

Мне нравится/хранить данные в оригинальной форме. i только убирать/фильтровать данные в зависимости от того, где я его использую.

  • на веб-странице - закодировать все html
  • on sql - kill quotes
  • на url - urlencoding
  • на принтерах - кодировать команды escape
  • о том, что когда-либо - закодировать его для этой работы

Ответ 3

Санируйте его для базы данных, прежде чем поместить в базу данных, если необходимо (т.е. если вы не используете уровень интерактивности базы данных, который обрабатывает это для вас). Санируйте его для отображения перед отображением.

Сохранение вещей в ненужной цитируемой форме просто вызывает слишком много проблем.

Ответ 4

Существует, по крайней мере, два типа фильтрации/дезинфекции, о которых вам следует заботиться:

  • SQL
  • HTML

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


С другой стороны, второй вопрос представляет собой более интересный вопрос:

  • если ваши пользователи должны иметь возможность редактировать свои данные, интересно вернуть их им так же, как они ввели его сначала; что означает, что вам нужно сохранить версию, отличную от html-specialchars-escaped.
  • Если вы хотите, чтобы какой-то HTML отображался, вы можете использовать что-то вроде HTMLPurifier: очень мощный... Но может потребоваться бит слишком много ресурсов, если вы запускаете его на всех данных, когда он должен отображаться...

Итак:

  • Если вы хотите отобразить некоторый HTML, используя тяжелый инструмент для проверки/фильтрации, я бы сказал, что вам нужно сохранить уже отфильтрованную/любую версию в базе данных, чтобы не уничтожать сервер, повторно создавая его каждый время отображения данных
    • но вам также нужно сохранить "оригинальную" версию (см. то, что я сказал ранее).
    • В этом случае я бы, вероятно, сохранил обе версии в базе данных, даже если это займет больше места... Или, по крайней мере, использовать какой-то хороший кэширующий mecanism, чтобы не обновлять чистую версию снова и снова.
  • Если вы не хотите отображать какой-либо HTML-код, вы будете использовать htmlspecialchars или эквивалент, который, вероятно, не такой большой, как у процессора-едока... Так что, вероятно, это не имеет большого значения
    • вам все равно нужно сохранить "оригинальную" версию
    • но экранирование при выводе данных может быть в порядке.

BTW, первое решение также хорошо, если пользователи используют что-то вроде bbcode/markdown/wiki при вводе данных, а вы их визуализируете в HTML...
По крайней мере, пока он отображается чаще, чем он обновляется, и особенно если вы не используете кеш для хранения чистой версии HTML.

Ответ 5

Я всегда говорю о спасении вещей, прежде чем передавать их в то место, где им нужно бежать. Ваша база данных не заботится о HTML, поэтому избегать HTML перед сохранением в базе данных не требуется. Если вы когда-либо хотите выводить как нечто иное, чем HTML, или изменить, какие теги разрешены/запрещены, у вас может быть немного работы впереди вас. Кроме того, легче помнить о том, что нужно выполнить эвакуацию, когда это нужно сделать, чем на более ранней стадии процесса.

Также стоит отметить, что строки с экранированным текстом могут быть намного длиннее исходного. Если я помещаю японское имя пользователя в регистрационную форму, исходной строкой могут быть только 4 символа Юникода, но экранирование HTML может преобразовать его в длинную строку "& # 12345; & # 67890; & # 18504; & # 31337;". Тогда мое 4-символьное имя пользователя слишком длинное для вашего поля базы данных и хранится в виде двух японских символов плюс половина кода выхода, что также, вероятно, мешает мне войти в систему.

Остерегайтесь того, что браузеры, как правило, избегают некоторых вещей, таких как неанглийский текст в самих представленных формах, и всегда будет тот smartass, который использует японское имя пользователя повсюду. Таким образом, вы можете захотеть на самом деле unescape HTML перед сохранением.

Ответ 6

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

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

С другой стороны, некоторые короткие семантические данные могут быть отфильтрованы немедленно. 1) Вы не хотите, чтобы в базе данных находились беспорядочные телефонные номера, поэтому для таких вещей было бы неплохо продезинфицировать. 2) Вы не хотите, чтобы какой-либо другой программист случайно выводил данные без экранирования, и вы работаете в среде мультипрограмммера. Однако в большинстве случаев исходные данные лучше IMO.