У меня есть веб-сайт Symfony, где пользователи могут упоминать других, комментируя сообщения. Когда комментарии отображаются, если есть теги "<" script ">", они также выполняются как javascript.
Example comment in the database: I think <a href = "https://www.examplesite.com/burak">@joanna</a> was right
Когда я визуализирую этот комментарий без «сырого» фильтра, теги HTML экранируются, и проблема исчезает. Однако вся ссылка отображается в комментариях, и упоминания больше не доступны для просмотра.
Я попробовал использовать настраиваемый фильтр ниже, но он тоже не сработал.
class FilterBlackListedExtension extends \Twig_Extension
{
private $blacklistedTags = ['script', 'p'];
public function getFilters()
{
return array(
new \Twig_SimpleFilter('filter_black_listed', array($this, 'htmlFilter')),
);
}
public function htmlFilter($html)
{
foreach ($this->blacklistedTags as $tag) {
preg_replace('/(<' . $tag . '>)(.*)(</' . $tag . '>)/', '', $html);
}
return $html; // maybe even apply the raw filter also afterwards.
}
public function getName()
{
return 'filter_black_listed_extension';
}
}
Что мне точно нужно, так это фильтр, который избегает javascript, но не HTML. Примечание: я уже пробовал escape ("js"), и это тоже не сработало. Он также поднял шестнадцатеричные символы в комментарии.




Вы можете использовать фильтр Twig striptags, чтобы экранировать все теги, кроме тех, которые вы хотите сохранить. Чтобы удалить теги html, но оставить ссылки в комментариях, сделайте следующее:
{{ comment_content|striptags('<a>') }}
Аргумент фильтра - это белый список тегов. Если вы хотите сохранить другие теги, просто добавьте их в строку:
{{ comment_content|striptags('<a><p><strong>') }}
Для информации, использование escape("js") не сработало, потому что оно предназначалось для выхода в javascript контекст, что означает внутри скрипта.
Warning : as pointed out by @fgb, javascript inserted in tags via event attributes like
<a onmouseover='alert(1)'>123</a>would be executed with this solution.
Что это делает с такими атрибутами, как: <a onmouseover='alert(1)'>123</a>?
Если вы хотите разрешить некоторый HTML, но избегать сценариев, вы можете использовать такой инструмент, как HTMLPurifier. Это проанализирует HTML и применит к нему настраиваемый белый список.
Могу поручиться за способности HTMLPurifier. Хотя это немного тяжеловесно, на моем собственном сайте я закончил кеширование очищенных результатов. Но что-то вроде HMTLPurifier также решает проблему в другом ответе с вредоносными атрибутами запуска сценария, такими как onmouseover, вы можете настроить HTMLPurifier, чтобы разрешить или удалить любые определенные атрибуты для любых конкретных элементов, которые вам нравятся.
Я также нашел пакет symfony, который я скоро попытаюсь обновить здесь. Вот ссылка на комплект. github.com/Exercise/HTMLPurifierBundle
Если вы хотите реализовать только функцию «упоминания», я думаю, вам не следует позволять пользователям сохранять HTML, а вместо этого преобразовывать данные упоминания в структуру, которая поможет вам сгенерировать вывод во время рендеринга. например input-> "Я думаю, что @joanna была права"-> перед тем, как сохранить эту строку в БД, вы преобразуете ее, например, в "Я думаю, что [упоминание-user-id = 42] @joanna [/ упоминание] было правильным". А затем вы создадите фильтр Twig, который анализирует эти теги и вместо этого генерирует привязки. Или вы можете вместо этого сохранить сообщение как обычный текст и сохранить в другом поле данные для создания ссылки.