Noty — это библиотека для отображения уведомлений в веб-приложениях.
Одним из важных аспектов работы с уведомлениями является безопасное
использование HTML внутри них. Библиотека поддерживает возможность
вставки HTML-контента через опцию text, однако некорректная
работа с пользовательским вводом может привести к XSS-уязвимостям.
Для безопасного отображения HTML необходимо разделять два сценария:
статический HTML-контент и контент, полученный
от пользователя. Статический HTML, определяемый в коде
разработчика, безопасен по умолчанию. Вставка пользовательского контента
требует обработки через функции экранирования специальных символов:
<, >, ", ',
&.
Пример базового уведомления с HTML:
new Noty({
type: 'success',
layout: 'topRight',
text: '<strong>Успех!</strong> Данные сохранены.',
timeout: 3000
}).show();
В этом примере HTML безопасен, так как строка задаётся разработчиком и не зависит от внешнего ввода.
Если необходимо вставить пользовательский текст, его нужно
обязательно экранировать, чтобы теги <script> или
другие потенциально опасные конструкции не выполнялись. Простая функция
экранирования может выглядеть так:
function escapeHTML(str) {
return str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
const userInput = '<img src=x oner ror=alert(1)>';
new Noty({
type: 'alert',
layout: 'topRight',
text: escapeHTML(userInput),
timeout: 4000
}).show();
После экранирования все специальные символы заменяются на безопасные HTML-сущности, что предотвращает выполнение скриптов.
Noty поддерживает кастомные шаблоны уведомлений через опцию
template. Для безопасного внедрения HTML рекомендуется
использовать шаблонизаторы, которые автоматически экранируют
пользовательские данные.
Пример шаблона с динамическим контентом:
const template = (title, message) => `
<div class="noty_message">
<h4>${escapeHTML(title)}</h4>
<p>${escapeHTML(message)}</p>
</div>
`;
new Noty({
type: 'information',
layout: 'topRight',
text: template('Внимание', userInput),
timeout: 5000
}).show();
Использование функций экранирования внутри шаблонов гарантирует, что любые теги или атрибуты, введённые пользователем, будут безопасно отображены как текст.
dangerouslyUseHTMLString и их ограниченияВ Noty существует возможность принудительного отображения HTML через
опцию dangerouslyUseHTMLString. Она предназначена
исключительно для контента, полностью контролируемого разработчиком.
new Noty({
type: 'success',
layout: 'topRight',
text: '<em>Операция завершена</em>',
dangerouslyUseHTMLString: true
}).show();
Использование этой опции с пользовательским вводом категорически не рекомендуется, так как она полностью отключает экранирование и делает уведомление уязвимым для XSS.
Для безопасного HTML можно применять CSS-стили без использования
style внутри пользовательских тегов. Например, отдельный
CSS-класс позволяет задавать оформление текста:
.noty_message strong {
color: green;
}
.noty_message p {
font-size: 14px;
}
В уведомлении:
new Noty({
type: 'success',
layout: 'topRight',
text: '<div class="noty_message"><strong>Успех!</strong><p>Данные сохранены.</p></div>',
timeout: 3000
}).show();
Такой подход обеспечивает визуальное оформление без риска внедрения вредоносного кода через инлайновые атрибуты.
При работе с динамическими данными, например, сообщениями с сервера, рекомендуется всегда экранировать HTML на клиенте или на сервере. Даже если данные передаются с HTTPS, нельзя доверять их содержимому.
fetch('/api/notifications')
.then(res => res.json())
.then(data => {
data.forEach(item => {
new Noty({
type: 'info',
layout: 'topRight',
text: escapeHTML(item.message),
timeout: 4000
}).show();
});
});
Каждое уведомление проходит через функцию экранирования перед отображением.
escapeHTML для пользовательского
ввода.dangerouslyUseHTMLString для динамических
данных.Следование этим правилам позволяет использовать возможности Noty с HTML без риска XSS и других уязвимостей.