После нескольких часов поиска ошибок, я выяснил причину одной из самых раздражающих ошибок.
Когда пользователи печатают сообщение на моем сайте, они могут озаглавить его с помощью простого текста и HTML-сущностей.
Это означает, что в некоторых случаях пользователи будут вводить заголовок с обычными изображениями объектов HTML, такими как это лицо. (͡ ° ͜ʖ ͡ °).
Чтобы предотвратить внедрение html, я использую htmlspecialchars (); на заголовок, и, к сожалению, он преобразует изображение в его HTML-формат сущности при выводе на страницу позже.
( ͡° ͜ʖ ͡°)
Я понял, что проблема здесь заключалась в том, что заголовок кодировался, как в примере выше, и htmlspecialchar, а также то, что я хотел, и кодирование возможного внедрения html, превращало амперсанд в сущностях в
&.
Отключив все амперсанды и изменив их обратно на & это решило мою проблему, и лицо получилось, как и ожидалось.
Однако я не уверен, что это все еще безопасно от вредоносного HTML. Безопасно ли декодировать амперсанды в вмененных пользователем названиях? Если нет, как я могу решить эту проблему?
Если ваши объекты отображаются в виде текста, то вы, вероятно, звоните htmlspecialchars()
дважды.
Если ты не звонишь htmlspecialchars()
если явно дважды, то, возможно, это автоматическое экранирование на стороне браузера, которое может произойти, если страница, содержащая форму, использует устаревшую однобайтовую кодировку, такую как Windows-1252. Такое автоматическое экранирование — единственный способ правильно представить символы, отсутствующие в наборе символов конкретной однобайтовой кодировки. Все текущие браузеры (включая Firefox, Opera и IE) делают это.
Убедитесь, что вы используете кодировку Unicode (в частности, UTF-8).
Чтобы использовать Юникод в качестве кодировки, добавьте <meta charset="utf-8" />
элемент к HEAD
раздел HTML-страницы, который содержит форму. И не забудьте сохранить саму HTML-страницу в кодировке UTF-8. Чтобы использовать Unicode в PHP, обычно достаточно использовать многобайтовый (mb_
с префиксом) строковые функции. Наконец, механизмы баз данных, такие как MySQL, поддерживают UTF-8 уже давно.
В качестве временного решения вы можете отключить перекодирование существующих объектов, установив 4-й параметр ($double_encode
) из htmlspecialchars()
функция к false
,
Прямого ответа нет. Вы можете отказаться <script...>
в <script...>
и заканчиваются неприятностями, однако похоже, что код был дважды закодирован — возможно, один раз на входе, а затем снова, когда вы выводите на экран. Если вы можете гарантировать, что он был дважды закодирован, то можно отменить один из них.
Тем не менее, лучшим решением является сохранение «сырого» значения в памяти, а также санитарная обработка / кодирование для вывода в базы данных, HTML, JSON и т. Д.
Итак, когда вы получаете ввод, санируйте его для чего-то, что вам не нужно, но на самом деле не конвертируйте его в HTML, не избегайте его или чего-либо еще на этом этапе. Сбросить его в базу данных, html кодировать при выводе на экран / xml и т. Д.