XSS в шаблонах сообщений

При работе с интернационализацией интерфейсов одной из наиболее недооценённых угроз становится внедрение пользовательских данных в строки сообщений, которые затем интерпретируются как HTML. Библиотеки форматирования сообщений, включая Globalize, часто используются совместно с шаблонами сообщений, ICU-синтаксисом и динамической подстановкой параметров. В этих сценариях возникает пересечение двух областей: локализация текста и безопасность веб-контента.

Основной риск заключается в том, что сообщение перестаёт быть просто строкой и начинает становиться частью DOM. При неправильной обработке переменных внутри шаблонов возможно выполнение произвольного HTML или JavaScript, что формирует класс уязвимостей XSS (Cross-Site Scripting).


Механизм формирования сообщений и точки внедрения данных

Система сообщений в интернационализации обычно опирается на шаблоны с параметрами:

  • строки перевода содержат плейсхолдеры
  • значения подставляются в рантайме
  • результат отображается в интерфейсе

В типичном сценарии Globalize работает с форматированием чисел, дат и сообщений через ICU MessageFormat. Несмотря на то, что сама библиотека ориентирована на данные, а не на HTML, уязвимости появляются на уровне интеграции с UI.

Опасные точки возникают при следующих условиях:

  • параметр подставляется в HTML-контекст без экранирования
  • переводчики используют HTML-разметку внутри строк
  • сообщения интерпретируются как innerHTML
  • динамические значения включают пользовательский ввод

Контекст исполнения и типы XSS в локализации

XSS в интернационализации проявляется в трёх основных формах:

Stored XSS через переводы

Переводы часто хранятся вне кода: в JSON, CMS, внешних сервисах. Если система допускает HTML в переводах, злоумышленник при наличии доступа к системе локализации способен внедрить вредоносный скрипт.

Особенность этого сценария — долговременность воздействия. После публикации перевод распространяется на все экземпляры интерфейса.


Reflected XSS через параметры сообщений

Шаблон сообщения может включать динамические значения:

  • имя пользователя
  • поисковый запрос
  • данные формы

Если значение подставляется без экранирования, оно становится частью DOM. В сочетании с интернационализацией проблема усиливается, так как форматирование сообщений часто объединяет несколько источников данных в одну строку.


DOM-based XSS при рендеринге локализованных строк

Даже при отсутствии серверной обработки уязвимость может возникнуть на клиенте. Если строка перевода вставляется в DOM через небезопасные методы, например innerHTML, появляется возможность исполнения скриптов.


Особенности ICU MessageFormat и ложное ощущение безопасности

ICU MessageFormat, используемый в экосистеме Globalize, поддерживает:

  • выбор форм по plural rules
  • вложенные выражения
  • форматирование чисел и дат

Однако сам формат не решает проблему XSS, поскольку:

  • он оперирует текстовыми данными
  • не гарантирует HTML-экранирование
  • допускает вставку произвольных строковых значений

Ключевая ошибка архитектуры заключается в предположении, что формализация шаблона автоматически делает вывод безопасным.


HTML-контекст против текстового контекста

Безопасность сообщений напрямую зависит от контекста вставки:

Текстовый контекст

Отображение через textContent или эквивалентные механизмы безопасно по умолчанию. В этом случае даже вредоносные строки интерпретируются как текст.

HTML-контекст

Использование innerHTML или аналогичных методов приводит к интерпретации строки как разметки. В этом режиме любые неподготовленные данные становятся потенциальным вектором атаки.

В интернационализации особенно опасны гибридные случаи, когда часть строки — статический перевод, а часть — динамическое значение.


Типичные ошибки интеграции Globalize в UI-слой

При использовании Globalize уязвимости возникают не в самой библиотеке, а в интеграции:

  • объединение переведённой строки с HTML-шаблоном через конкатенацию
  • вставка результата форматирования напрямую в DOM как HTML
  • использование переводов как источника HTML-фрагментов
  • отсутствие различия между “message” и “markup message”

Особенно опасна практика, при которой переводчикам разрешается использовать HTML-теги для стилизации. Это переносит контроль над разметкой в слой, который не контролируется разработчиком приложения.


Экранирование как обязательный слой защиты

Базовая модель защиты строится на принципе:

  • все данные считаются небезопасными
  • экранирование выполняется на границе вывода

В контексте сообщений это означает:

  • параметры сообщений должны экранироваться до подстановки
  • либо результат должен вставляться как текст
  • либо используется строго контролируемый шаблонизатор

Критическая ошибка — экранирование только части данных. Например, экранирование имени пользователя при игнорировании перевода или наоборот не устраняет уязвимость.


Санитизация HTML в переводах и её ограничения

Иногда применяется подход с очисткой HTML внутри переводов. Однако он имеет ограничения:

  • сложность определения допустимого набора тегов
  • риск обхода фильтров через атрибуты событий
  • зависимость от реализации санитайзера
  • различия между браузерными движками

Санитизация не должна рассматриваться как основной механизм защиты в интернационализации. Она может использоваться только как дополнительный слой в ограниченных сценариях.


Безопасные модели рендеринга сообщений

Практика безопасной интернационализации опирается на разделение:

  • данные (values)
  • сообщения (messages)
  • представление (view layer)

Корректная модель предполагает:

  • сообщения всегда возвращают текст
  • форматирование не содержит HTML
  • UI-слой отвечает за разметку
  • любые вставки проходят экранирование

Такой подход исключает смешение ответственности между локализацией и рендерингом.


Паттерны предотвращения XSS в интернационализированных системах

Строго текстовые переводы

Переводы содержат только текст без HTML. Любая стилизация выполняется через CSS и компонентный слой.

Параметризованные сообщения

Все динамические значения передаются как параметры, не как часть строки.

Запрет HTML в локализации

Система хранения переводов не допускает HTML-тегов на уровне схемы данных.

Контролируемый рендеринг

Отображение происходит через безопасные API, которые исключают интерпретацию строки как HTML.


Роль архитектуры приложения в предотвращении уязвимостей

Уязвимости XSS в локализации почти всегда являются следствием архитектуры, а не библиотеки форматирования. Даже корректно используемая Globalize не может защитить от:

  • небезопасной вставки в DOM
  • отсутствия разделения контекстов
  • передачи HTML через переводческие строки

Безопасность формируется на уровне границ между слоями системы, а не внутри механизма форматирования сообщений.


Особенности многоязычных интерфейсов и расширение поверхности атаки

Интернационализация увеличивает количество строк и контекстов отображения, что приводит к:

  • росту количества точек вывода данных
  • увеличению числа переводов, подверженных модификации
  • сложностям аудита строк

Каждый новый язык фактически дублирует поверхность возможной атаки, если отсутствует строгий контроль формата сообщений.


Динамические шаблоны и риск цепочек подстановки

Сложные шаблоны сообщений могут включать вложенные выражения, где:

  • один параметр зависит от другого
  • данные проходят несколько уровней форматирования
  • промежуточные значения не экранируются

В таких цепочках XSS может возникнуть не на первом этапе, а при финальном рендеринге, что затрудняет обнаружение.


Контроль источников данных для сообщений

Критическим элементом защиты является классификация источников:

  • доверенные (переводы, системные строки)
  • частично доверенные (серверные данные)
  • недоверенные (пользовательский ввод)

В интернационализированных системах ошибка часто заключается в смешении этих категорий внутри одного сообщения.


Итоговая модель безопасной интернационализации

Безопасное использование сообщений в связке с Globalize строится на строгом разделении:

  • форматирование не должно интерпретировать HTML
  • UI-слой контролирует разметку
  • все значения проходят экранирование
  • переводы рассматриваются как данные, а не как код

Такой подход минимизирует риск XSS даже в сложных многоязычных интерфейсах, где количество динамических сообщений и контекстов отображения значительно возрастает.