Content Security Policy

Content Security Policy (CSP) представляет собой механизм защиты веб-приложений, ограничивающий источники загрузки и выполнения ресурсов. При интеграции с i18next в клиентских приложениях CSP становится критическим фактором архитектуры, поскольку система интернационализации опирается на динамическую загрузку переводов, выполнение шаблонов и работу с асинхронными загрузчиками ресурсов.

Базовые принципы CSP, влияющие на i18next

CSP управляет следующими аспектами, непосредственно затрагивающими работу i18next:

  • загрузка скриптов (script-src)
  • выполнение inline-скриптов
  • динамическая генерация кода (unsafe-eval)
  • загрузка XHR/fetch ресурсов (connect-src)
  • загрузка JSON-файлов переводов
  • использование Web Workers при расширенных конфигурациях

i18next в браузере обычно опирается на загрузчики ресурсов (backend plugins), которые используют fetch или XMLHttpRequest. При строгих CSP-политиках это требует явного разрешения соответствующих источников.

Ограничения выполнения скриптов

Одним из наиболее чувствительных аспектов CSP является запрет inline-скриптов. Многие приложения интернационализации исторически используют встроенную инициализацию:

<script>
  i18next.init({
    lng: 'en',
    resources: {
      en: {
        translation: {
          key: 'value'
        }
      }
    }
  });
</script>

При политике CSP без unsafe-inline такой код блокируется. Альтернативный подход предполагает вынесение инициализации в отдельный файл:

import i18next from 'i18next';

i18next.init({
  lng: 'en',
  fallbackLng: 'en',
  backend: {
    loadPath: '/locales/{{lng}}/{{ns}}.json'
  }
});

И подключение через разрешённый источник:

<script src="/assets/app.js"></script>

Запрет unsafe-eval и его влияние

Некоторые конфигурации i18next или связанных плагинов могут косвенно затрагивать eval-подобное поведение. CSP-параметр unsafe-eval блокирует динамическое выполнение строкового кода.

На практике современные версии i18next не используют eval, однако риск возникает при:

  • устаревших плагинах интерполяции
  • кастомных обработчиках шаблонов
  • интеграции с legacy-шаблонизаторами

Рекомендуемая конфигурация CSP исключает unsafe-eval, при этом проверяется совместимость всех зависимостей.

Загрузка переводов через HTTP и fetch

Основной сценарий работы i18next в production — загрузка переводов через backend:

import Backend from 'i18next-http-backend';
import i18next from 'i18next';

i18next
  .use(Backend)
  .init({
    lng: 'en',
    backend: {
      loadPath: '/locales/{{lng}}/{{ns}}.json'
    }
  });

CSP должна явно разрешать домен загрузки:

Content-Security-Policy:
  default-src 'self';
  script-src 'self';
  connect-src 'self';
  img-src 'self';
  style-src 'self';

При загрузке переводов с CDN:

connect-src 'self' https://cdn.example.com;

Любое несоответствие приводит к блокировке XHR/fetch запросов, что делает систему локализации неработоспособной.

Работа с JSON-ресурсами переводов

i18next использует JSON как основной формат хранения переводов. CSP не ограничивает JSON напрямую, однако ограничения накладываются через connect-src и default-src.

При архитектуре с разделением namespaces:

i18next.init({
  ns: ['common', 'auth', 'dashboard'],
  defaultNS: 'common'
});

запросы к ресурсам приобретают форму:

/locales/en/common.json
/locales/en/auth.json

Каждый endpoint должен быть разрешён политикой CSP.

Интеграция с CDN и строгими CSP-политиками

При использовании CDN для переводов или статических ресурсов возникает необходимость расширения CSP:

connect-src 'self' https://i18n.cdn.example.com;

и при необходимости:

img-src 'self' https://images.cdn.example.com;

Если перевод включает HTML-строки или rich-text содержимое, усиливается риск XSS, и CSP должна быть дополнена trusted-types (в современных браузерах):

require-trusted-types-for 'script';

Interpolation и потенциальные CSP-конфликты

Механизм интерполяции i18next:

i18next.t('welcome', { name: userName });

сам по себе безопасен, однако риск возникает при:

  • использовании dangerouslySetInnerHTML (React)
  • вставке переведённых строк как HTML без экранирования
  • подключении кастомных форматтеров

CSP не предотвращает логические XSS напрямую, но усиливает защитный контур при запрете inline HTML и скриптов.

HTML-режим и риск нарушения CSP

Некоторые конфигурации используют:

i18next.t('html_key', { interpolation: { escapeValue: false } });

При отключении экранирования возможна вставка HTML, что в сочетании с ослабленной CSP (unsafe-inline) увеличивает поверхность атаки.

Рекомендуемая практика:

  • сохранение escapeValue: true
  • запрет unsafe-inline
  • избегание HTML в переводах

Service Worker и локализация

В архитектурах PWA переводы часто кэшируются через Service Worker:

self.addEventListener('fetch', event => {
  if (event.request.url.includes('/locales/')) {
    event.respondWith(caches.match(event.request));
  }
});

CSP должна учитывать:

worker-src 'self';

и корректную настройку connect-src, если Service Worker делает сетевые запросы к источникам переводов.

Политика nonce и модульная архитектура

При строгой CSP с nonce:

Content-Security-Policy: script-src 'self' 'nonce-random123'

инициализация i18next должна выполняться исключительно в внешних модулях, загруженных через разрешённые скрипты:

// app.js
import i18next from 'i18next';

export function initI18n() {
  return i18next.init({
    lng: 'en'
  });
}

Inline-конфигурации исключаются полностью.

Типичные конфигурации CSP для i18next-приложений

Базовая безопасная конфигурация:

Content-Security-Policy:
  default-src 'self';
  script-src 'self';
  connect-src 'self';
  img-src 'self';
  style-src 'self';

Расширенная конфигурация с CDN:

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://cdn.example.com;
  connect-src 'self' https://i18n.cdn.example.com;
  img-src 'self' https://assets.cdn.example.com;
  style-src 'self';

Диагностика блокировок CSP при использовании i18next

При нарушении CSP поведение обычно проявляется следующим образом:

  • отсутствует загрузка переводов

  • t() возвращает ключи вместо значений

  • XHR запросы к /locales/* блокируются

  • ошибки в консоли вида:

    • “Refused to connect to … due to Content Security Policy”

Диагностика сводится к анализу:

  • connect-src
  • источников backend загрузчика
  • наличия CDN-доменов
  • политики default-src

Архитектурные подходы для CSP-совместимости

Наиболее устойчивые подходы включают:

  • отказ от inline-конфигураций i18next
  • централизованная загрузка переводов через backend plugin
  • кэширование через Service Worker
  • минимизация сторонних доменов
  • строгий контроль namespaces и endpoints
  • исключение HTML-интерполяции в переводах

При соблюдении этих ограничений i18next функционирует в строгих CSP-окружениях без деградации функциональности локализации.