В i18next интерполяция значений выполняется через синтаксис
{{ key }} внутри переводов. При подстановке значений
библиотека по умолчанию применяет экранирование специальных
HTML-символов, чтобы предотвращать внедрение разметки в итоговую
строку.
При интерполяции происходит преобразование потенциально опасных символов:
< → <> → >& → &" → "' → 'Это поведение связано с защитой от XSS-уязвимостей в тех случаях, когда перевод или интерполируемые данные попадают напрямую в DOM.
Ключевой механизм управления экранированием задаётся через конфигурацию интерполяции:
i18next.init({
interpolation: {
escapeValue: true
}
});
escapeValue: trueПри включённом экранировании все значения, вставляемые через
{{ }}, проходят через функцию escape. Это безопасное
поведение для классического DOM-рендеринга:
{
"welcome": "Hello, {{name}}"
}
i18next.t('welcome', { name: '<script>alert(1)</script>' });
Результат:
Hello, <script>alert(1)</script>
HTML-код не интерпретируется браузером как разметка.
escapeValue: falseОтключение экранирования приводит к прямой подстановке значений без преобразования:
i18next.init({
interpolation: {
escapeValue: false
}
});
В этом режиме:
Hello, <script>alert(1)</script>
Данный режим допустим только в средах, где экранирование выполняется на другом уровне (например, React).
i18next поддерживает механизм вставки «сырых» HTML-значений через тройные фигурные скобки:
{{{html}}}
Пример:
{
"content": "Text: {{{value}}}"
}
i18next.t('content', {
value: '<strong>bold</strong>'
});
Результат:
Text: <strong>bold</strong>
HTML интерпретируется браузером как разметка и не экранируется.
Использование такого подхода полностью обходит защитный слой интерполяции и переносит ответственность за безопасность на уровень данных.
{{ }} и
{{{ }}}| Синтаксис | Поведение | Экранирование | Результат |
|---|---|---|---|
{{ key }} |
интерполяция | включено по умолчанию | текст |
{{{ key }}} |
сырая вставка | отключено | HTML |
Двойные скобки предназначены для безопасной подстановки значений, тройные — для управляемого внедрения HTML.
В средах, использующих виртуальный DOM (например, React), дополнительное экранирование часто уже встроено на уровне рендера.
Поэтому конфигурация i18next обычно включает:
i18next.init({
interpolation: {
escapeValue: false
}
});
Причина заключается в том, что React самостоятельно преобразует строки в безопасное отображение, предотвращая прямое выполнение HTML.
Однако даже в таких условиях использование {{{ }}} может
приводить к небезопасной вставке через
dangerouslySetInnerHTML, если данные не контролируются.
Отключение escapeValue или использование тройных скобок
создаёт риск внедрения скриптов, если входные данные не фильтруются.
Типичный сценарий:
i18next.t('message', {
name: userInput
});
Если userInput содержит HTML или JavaScript, он может
быть внедрён в DOM при отсутствии экранирования.
Особенно опасны комбинации:
{{{ }}}escapeValueЭкранирование становится обязательным при:
innerHTMLПри необходимости работы с HTML содержимым применяется явная санитизация данных до передачи в i18next.
Пример концептуальной обработки:
function sanitize(input) {
return input.replace(/</g, '<').replace(/>/g, '>');
}
Затем уже безопасное значение передаётся в интерполяцию:
i18next.t('text', {
value: sanitize(userInput)
});
i18next поддерживает post-processing плагинизацию, где итоговая строка может дополнительно модифицироваться после интерполяции.
На этом этапе возможно:
Однако любые операции на этом уровне должны учитывать, что интерполяция уже могла изменить исходные данные.
i18next допускает вложенные значения:
{
"outer": "Value: {{inner}}"
}
i18next.t('outer', {
inner: i18next.t('innerKey')
});
Если внутренний перевод содержит HTML или небезопасные данные, экранирование применяется только на уровне финальной строки, что может привести к неожиданным результатам при комбинировании режимов.
При включённой опции returnObjects интерполяция может
работать с вложенными структурами:
i18next.t('key', { returnObjects: true });
Если такие данные используются в UI без корректного рендера,
экранирование может оказаться недостаточным, поскольку объекты могут
быть преобразованы в строки через toString().
Вся модель экранирования в i18next опирается на разделение данных по источнику:
При смешивании этих источников в одной интерполяции риск XSS возрастает линейно с уменьшением контроля над данными.
Процесс интерполяции можно представить как последовательность этапов:
{{ }} или
{{{ }}}Любое отключение экранирования или использование «сырых» вставок изменяет конечный результат уже на этапе 4, что делает последующие этапы критичными для безопасности DOM-вывода.