flawopen.com/XSS в JavaScript/dangerouslySetInnerHTML
Безопасен ли dangerouslySetInnerHTML в React?
Представьте обычный JSX как принтер этикеток: текст остаётся текстом. dangerouslySetInnerHTML переключает его на печатный станок, который разбирает строку как HTML. Если строка содержит данные под контролем атакующего, браузер может воспринять их как активную разметку. Используйте эту точку только для намеренно доверенного HTML или HTML, очищенного для конкретного контекста.
Почему обычному JSX это не нужно
function Comment({ html }) {
return <p dangerouslySetInnerHTML=
{{ __html: html }} />;
}
function Comment({ text }) {
return <p>{text}</p>;
}
Когда уместен dangerouslySetInnerHTML?
Используйте его только тогда, когда продукту необходимо сохранить ограниченный формат rich text, который нельзя представить обычными дочерними узлами React. CMS, редактор или Markdown-рендерер не становятся доверенными автоматически: сохранённый контент и результат рендерера могут содержать недоверенную разметку. Определите разрешённые элементы и атрибуты, очистите содержимое поддерживаемой библиотекой, например DOMPurify, и передайте результат в эту точку без дальнейших изменений.
Правильное применение
Очищайте значение непосредственно перед передачей в dangerouslySetInnerHTML с помощью поддерживаемой библиотеки, например DOMPurify. Не используйте регулярные выражения для очистки HTML. Не изменяйте строку после очистки: последующее преобразование может нарушить гарантии. Обновляйте библиотеку и среду разбора.
Список запретов для известных тегов неполон: риск может исходить от атрибутов, URL-полей, пространств имён и поведения парсера. Составьте небольшой список необходимых элементов и атрибутов и настройте очиститель согласно ему. Отдельно проверьте ссылки и другие URL-атрибуты с учётом разрешённых продуктом адресов.
Как проверить код
grep -rn "dangerouslySetInnerHTML" --include="*.jsx" --include="*.tsx" .Частые вопросы
Это зависит от рендерера и его настроек. Проверьте, разрешён ли необработанный HTML и очищается ли результат; одно преобразование Markdown не делает HTML безопасным.
Да. v-html также передаёт HTML браузеру без обычной текстовой интерполяции фреймворка. Считайте его HTML-точкой вывода и очищайте недоверенное содержимое по подходящей политике.
Источники
- Документация React — dangerouslySetInnerHTML
- DOMPurify — HTML-очиститель и рекомендации
- MDN — меры безопасности для Element.innerHTML
- flawopen.com — XSS в JavaScript