Фреймворк Lit предоставляет мощные средства для создания веб-компонентов с использованием шаблонов на основе шаблонных литералов JavaScript. Одним из ключевых аспектов при работе с динамическими данными в этих шаблонах является защита от XSS (Cross-Site Scripting).
В Lit все данные, вставляемые через интерполяцию (${}) в
шаблон, автоматически экранируются при вставке в
текстовый контент HTML. Это значит, что если в переменной содержится
пользовательский ввод с потенциально опасными символами
(<, >, &,
", '), они будут преобразованы в безопасные
HTML-сущности:
import { html, LitElement } from 'lit';
class SafeComponent extends LitElement {
static properties = {
userInput: { type: String }
};
constructor() {
super();
this.userInput = '<script>alert("XSS")</script>';
}
render() {
return html`<p>${this.userInput}</p>`;
}
}
customElements.define('safe-component', SafeComponent);
В этом примере <script> не выполнится, так как Lit
преобразует его в безопасный текст:
<script>alert("XSS")</script>.
Для вставки сырых HTML или атрибутов существует директива
unsafeHTML из пакета
lit/directives/unsafe-html.js. Использование этой директивы
обходит автоматическое экранирование, поэтому она может
стать источником XSS:
import { html, LitElement } from 'lit';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
class UnsafeComponent extends LitElement {
static properties = {
rawHtml: { type: String }
};
constructor() {
super();
this.rawHtml = '<img src=x oner ror=alert(1)>';
}
render() {
return html`${unsafeHTML(this.rawHtml)}`;
}
}
customElements.define('unsafe-component', UnsafeComponent);
В данном случае <img> с обработчиком события
onerror выполнится, что создаёт уязвимость. Использование
unsafeHTML допустимо только с доверенными источниками
данных.
Lit различает атрибуты и свойства
элементов. Атрибуты HTML передаются через
.attrName="${value}", а свойства — через
.propName=${value}.
html`<input .value=${userInput}>`
В этом примере значение userInput не интерпретируется
как HTML, так как это свойство DOM value.
Динамическая привязка обработчиков событий через Lit безопасна, так
как она использует прямое присваивание свойств
on[event].
html`<button @click=${this.handleClick}>Нажать</button>`
Передача пользовательского кода через событие невозможна. Необходимо
избегать использования eval или присваивания строк к
обработчикам событий.
Некоторые директивы Lit повышают безопасность:
guard — предотвращает лишние перерисовки и минимизирует
потенциальные векторы XSS при работе с динамическими данными.repeat — безопасно рендерит массивы объектов,
автоматически экранируя текстовые значения.Пример безопасного рендеринга списка:
import { repeat } from 'lit/directives/repeat.js';
html`
<ul>
${repeat(items, item => item.id, item => html`<li>${item.text}</li>`)}
</ul>
`;
Все item.text экранируется автоматически.
unsafeHTML с пользовательскими
данными без предварительной очистки.repeat, guard) для минимизации ручного
вмешательства в HTML.Lit сочетает удобство шаблонов с встроенной защитой, но при обходе механизмов экранирования разработчик несёт полную ответственность за безопасность приложения.