Санитизация пользовательского ввода в интернационализационных системах играет критическую роль, поскольку переводимые строки часто формируются динамически и включают данные, поступающие извне. В экосистеме i18next этот аспект встроен в механизм интерполяции и требует понимания внутренних правил обработки значений, подстановок и экранирования.
Основная опасность связана с тем, что переводимые строки нередко содержат HTML-контекст или используются в UI-фреймворках, которые могут интерпретировать строку как разметку. При отсутствии санитизации возможны следующие проблемы:
Особенно уязвимы случаи, когда перевод хранится на сервере или загружается из внешнего backend-источника и не проходит предварительную очистку.
i18next использует систему интерполяции вида:
i18next.t('welcome_user', { name: userInput })
Внутри строки перевода:
{
"welcome_user": "Добро пожаловать, {{name}}"
}
Ключевой момент — интерполяция по умолчанию экранирует значения. Это поведение регулируется параметром:
interpolation: {
escapeValue: true
}
При escapeValue: true специальные символы HTML
преобразуются в безопасные сущности, предотвращая вставку исполняемого
HTML.
Пример трансформации:
<script>alert(1)</script><script>alert(1)</script>Таким образом, даже если пользовательский ввод содержит HTML, он отображается как текст.
Отключение защиты:
i18next.init({
interpolation: {
escapeValue: false
}
});
Такой режим используется редко и только в окружениях, где санитизация выполняется на другом уровне. При этом интерполяция начинает подставлять значения «как есть», что делает систему уязвимой к XSS при наличии HTML-контекста.
Особенно опасно сочетание:
{
"greeting": "Hello <strong>{{name}}</strong>"
}
и пользовательского ввода, содержащего HTML-теги.
Безопасная архитектура предполагает строгую сегрегацию:
t()Пример безопасного подхода:
const safeName = sanitize(userInput);
t('greeting', { name: safeName });
Где sanitize выполняет удаление или нейтрализацию
опасных конструкций.
При использовании React или аналогичных библиотек часто встречается паттерн:
<div dangerouslySetInnerHTML={{ __html: t('html_string') }} />
В таком случае i18next перестаёт быть точкой защиты, потому что строка интерпретируется как HTML.
Безопасная модель требует:
Даже при включённом escapeValue опасность сохраняется,
если перевод содержит заранее подготовленный HTML.
i18next позволяет переопределять логику экранирования:
i18next.init({
interpolation: {
escape: (value) => {
return customEscape(value);
}
}
});
Такой подход используется для:
Типичная реализация:
function customEscape(str) {
return str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
При использовании ICU-подобных структур (pluralization, context rules) данные также могут включать пользовательские значения:
{
"items": "У вас {count, number} сообщений"
}
Хотя числовые значения менее опасны, форматные поля всё равно требуют контроля:
При использовании backend-плагинов i18next переводы могут загружаться динамически:
Основной риск возникает, если атакующий получает возможность модифицировать перевод:
{
"welcome": "Hello <img src=x oner ror=alert(1)>"
}
Такие строки обходят стандартную интерполяцию, потому что опасный код уже находится в самом переводе.
Следовательно, санитизация должна применяться:
i18next поддерживает postProcess плагины:
i18next.t('key', {
postProcess: 'myProcessor'
});
Эта стадия может модифицировать результат перевода после интерполяции, что создаёт дополнительную точку риска:
Без строгого контроля postProcess способен полностью нивелировать встроенную защиту интерполяции.
Наиболее устойчивый подход строится вокруг нескольких принципов:
Пример разделения:
// небезопасно
t('text', { html: userHtml });
// безопасно
t('text', { name: sanitizedName });
В React-экосистеме i18next часто используется через обёртки. Несмотря на автоматическое экранирование React, оно не заменяет защиту i18next:
Особенно уязвимы гибридные схемы, где перевод вставляется в raw HTML.
escapeValue без альтернативной защиты;dangerouslySetInnerHTML без
санитизации;Каждая из этих ошибок превращает i18next из слоя локализации в потенциальную точку внедрения уязвимостей.
Стабильная модель санитизации в системах с i18next опирается на разделение обязанностей:
При соблюдении этих принципов интерполяция остаётся предсказуемой, а риск инъекций сводится к контролируемым границам обработки данных.