Когда фильтровать / обрабатывать данные: до вставки базы данных или до отображения?
Готовясь к решению проблемы фильтрации и очистки входных данных, мне интересно, есть ли лучшая (или наиболее используемая) практика? Лучше ли фильтровать / очищать данные (HTML, JavaScript и т. Д.) Перед вставкой данных в базу данных, или это следует делать, когда данные готовятся для отображения в HTML?
Несколько заметок:
- Я делаю это в PHP, но я подозреваю, что ответ на этот вопрос не зависит от языка. Но если у вас есть какие-либо рекомендации, относящиеся к PHP, пожалуйста, поделитесь!
- Это не проблема экранирования данных для вставки базы данных. У меня уже есть PDO, который справляется с этим довольно хорошо.
Спасибо!
6 ответов
Когда дело доходит до отображения данных, представленных пользователем, общепринятая мантра - "Фильтровать ввод, экранировать вывод".
Я бы рекомендовал избегать экранирования таких вещей, как html-сущности и т. Д., Прежде чем войти в базу данных, потому что вы никогда не знаете, когда HTML не будет вашим средством отображения. Кроме того, разные типы ситуаций требуют разных типов выхода. Например, встраивание строки в Javascript требует другого экранирования, чем в HTML. Если вы сделаете это раньше, у вас может возникнуть ложное чувство безопасности.
Итак, основное эмпирическое правило: продезинфицировать перед использованием и специально для этого использования; не преимущественно.
(Обратите внимание, я не говорю о экранировании вывода для SQL, только для отображения. Пожалуйста, по-прежнему выполняйте экранирование данных, привязанных к строке SQL).
Мне нравится иметь / хранить данные в оригинальном виде. Я только экранирую / фильтрую данные в зависимости от того, где я их использую.
- на веб-странице - закодировать все HTML
- на sql - убить цитаты
- по URL - urlencoding
- на принтерах - кодировать escape-команды
- на что когда-либо - закодировать его для этой работы
Существует как минимум два типа фильтрации / очистки, о которых вам следует позаботиться:
- SQL
- HTML
Очевидно, что о первом необходимо позаботиться до / при вставке данных в базу данных, чтобы предотвратить SQL-инъекции.
Но вы уже знаете это, как вы сказали, поэтому я не буду больше об этом говорить.
Второй, с другой стороны, является более интересным вопросом:
- если ваши пользователи должны иметь возможность редактировать свои данные, интересно вернуть их им так же, как они вводили их сначала; Это означает, что вы должны хранить "не-html-specialchars-escape-версию".
- если вы хотите, чтобы какой-то HTML отображался, вы можете использовать что-то вроде HTMLPurifier: очень мощный... Но может потребоваться слишком много ресурсов, если вы запускаете его для всех данных, когда они должны отображаться...
Так:
- Если вы хотите отобразить некоторый HTML-код, используя тяжелый инструмент для его проверки / фильтрации, я бы сказал, что вам нужно сохранить уже отфильтрованную / любую версию в базу данных, чтобы не уничтожать сервер, создавая его заново каждый раз, когда данные отображается
- но вам также нужно хранить "оригинальную" версию (посмотрите, что я говорил раньше)
- В этом случае я бы, вероятно, сохранил обе версии в базе данных, даже если это займет больше места... Или, по крайней мере, использовал бы хороший механизм кэширования, чтобы не воссоздавать чистую версию снова и снова.
- Если вы не хотите отображать HTML, вы будете использовать
htmlspecialchars
или эквивалент, который, вероятно, не так уж много потребляет процессор... Так что это, вероятно, не имеет большого значения- вам все еще нужно хранить "оригинальную" версию
- но экранирование при выводе данных может быть в порядке.
Кстати, первое решение также хорошо, если пользователи используют что-то вроде bbcode/markdown/wiki при вводе данных, и вы отображаете это в HTML...
По крайней мере, до тех пор, пока он отображается чаще, чем обновляется, особенно если вы не используете кеш для хранения чистой HTML-версии.
Я всегда говорю избегать вещей непосредственно перед тем, как передать их туда, куда им нужно бежать. Ваша база данных не заботится о HTML, поэтому экранирование HTML перед сохранением в базе данных не требуется. Если вы когда-нибудь захотите выводить что-то, отличное от HTML, или изменить какие теги разрешены / запрещены, у вас может быть немного работы впереди. Кроме того, легче не забыть делать правильное побег, когда это необходимо, чем на более ранней стадии процесса.
Стоит также отметить, что экранированные HTML-строки могут быть намного длиннее исходного ввода. Если я добавлю японское имя пользователя в форму регистрации, исходная строка может содержать только 4 символа Юникода, но экранирование HTML может преобразовать его в длинную строку "& # 12345; & # 67890; & # 18504; & # 31337;", Тогда мое 4-символьное имя пользователя будет слишком длинным для поля вашей базы данных и будет сохранено в виде двух японских символов плюс половина escape-кода, что также, вероятно, не позволяет мне войти в систему.
Помните, что браузеры имеют тенденцию избегать некоторых вещей, таких как неанглийский текст в отправленных формах, и всегда найдется тот умник, который везде использует японское имя пользователя. Так что вы можете захотеть удалить HTML перед сохранением.
Очистите его для базы данных, прежде чем помещать в базу данных, если это необходимо (например, если вы не используете слой интерактивности базы данных, который обрабатывает это для вас). Санируйте его для показа перед показом.
Хранение вещей в ненужной в настоящее время форме в кавычках просто вызывает слишком много проблем.
В основном это зависит от того, что вы планируете делать со входом, а также от вашей среды разработки.
В большинстве случаев вы хотите оригинальный ввод. Таким образом, вы получаете возможность настраивать свою продукцию в соответствии с вашим сердцем, не боясь потерять оригинал. Это также позволяет вам устранять проблемы, такие как неправильный вывод. Вы всегда можете увидеть, как ваши фильтры глючат или ввод клиента ошибочен.
С другой стороны, некоторые короткие семантические данные могут быть отфильтрованы немедленно. 1) Вы не хотите, чтобы в базе данных были грязные номера телефонов, поэтому для таких вещей было бы хорошо провести санитарную обработку. 2) Вы не хотите, чтобы какой-то другой программист случайно выводил данные без экранирования, и вы работаете в многопрограммной среде. Однако в большинстве случаев исходные данные лучше ИМО.