Best practices безопасности

Stencil строится вокруг веб-компонентов, что уже подразумевает высокий уровень инкапсуляции. Каждый компонент имеет отдельный DOM и Shadow DOM, что ограничивает возможность случайного вмешательства извне. Использование Shadow DOM помогает изолировать стили и поведение, предотвращая утечку данных и перекрытие стилей из глобального пространства.

Важно проектировать компоненты так, чтобы они имели минимальное внешнее API. Экспортировать следует только те свойства и методы, которые действительно нужны для взаимодействия. Излишняя открытость делает компонент более уязвимым к XSS-атакам и непреднамеренному изменению состояния.

Работа с данными и свойствами

Stencil предоставляет возможность работы с @Prop, @State и @Event.

  • @Prop — свойства, которые могут передаваться извне. Важно проверять и валидировать входящие данные, особенно если они влияют на рендеринг HTML. Это снижает риск внедрения вредоносного кода.
  • @State — внутреннее состояние компонента. Использование @State безопасно, так как данные не доступны извне напрямую.
  • @Event — события, которыми компонент уведомляет внешние сущности. Следует избегать передачи чувствительных данных через события без шифрования или безопасной сериализации.

Для всех входных данных рекомендуется использовать sanitize-функции, особенно если они могут содержать HTML или выполняться в контексте DOM.

Работа с DOM и безопасный рендеринг

Stencil использует JSX для описания шаблонов. При работе с JSX нужно строго следить за тем, что вставляется в innerHTML. Прямое присвоение HTML без очистки открывает двери для XSS-атак.

  • Использование конструкции <div innerHTML={sanitize(html)}> вместо <div innerHTML={rawHtml}> предотвращает внедрение скриптов.
  • Для динамических классов или атрибутов рекомендуется применять строго типизированные и проверенные значения.

Асинхронные операции и обработка ошибок

Компоненты Stencil часто взаимодействуют с API через fetch или другие асинхронные операции. Следует:

  • Всегда проверять ответы сервера и обрабатывать ошибки.
  • Избегать использования данных из ненадежных источников без проверки.
  • Ограничивать доступ к компоненту только проверенными токенами или ключами API.

Асинхронные операции следует помещать в lifecycle методы, такие как componentWillLoad или componentDidLoad, чтобы контролировать состояние компонента до и после получения данных.

Управление состоянием и реактивность

Reactivity в Stencil построена на @State и реакциях на изменения пропсов. Для безопасности:

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

Подписи и авторизация

Для компонентов, которые делают изменения данных на сервере, критично:

  • Использовать JWT или OAuth для проверки прав пользователя.
  • Не доверять данным на клиенте. Любая проверка должна повторяться на сервере.
  • Ограничивать количество и тип данных, передаваемых компонентом, до минимально необходимого.

CSP и защита от XSS

Stencil хорошо сочетается с Content Security Policy (CSP). Рекомендуется:

  • Запрещать выполнение inline-скриптов.
  • Ограничивать загрузку ресурсов только с доверенных источников.
  • Использовать nonce или hash для безопасного включения скриптов, если это необходимо.

Применение CSP в комбинации с Shadow DOM снижает риски внедрения вредоносного кода и утечки данных через DOM.

Оптимизация безопасности стилей

Shadow DOM изолирует стили, но важно также:

  • Не импортировать внешние CSS с ненадежных источников.
  • Использовать строго типизированные CSS-переменные для динамических значений.
  • Избегать inline-стилей, содержащих динамический контент, полученный извне.

Аудит и тестирование безопасности

Stencil позволяет интегрировать unit и e2e тесты с Cypress, Jest и Puppeteer. Для безопасности:

  • Покрывать тестами сценарии XSS, CSRF и утечки данных.
  • Проводить автоматизированные проверки на уязвимости при сборке.
  • Регулярно проверять зависимости на известные CVE.

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