Content Security Policy (CSP) — это механизм безопасности веб-приложений, предназначенный для предотвращения атак типа XSS (Cross-Site Scripting) и других инъекций. CSP позволяет строго ограничить источники загрузки скриптов, стилей, медиафайлов и других ресурсов, что особенно важно при работе с современными JavaScript-фреймворками, включая Stimulus.
Stimulus — это легковесный фреймворк, ориентированный на управление поведением HTML через контроллеры, связывая действия с элементами DOM без необходимости полного SPA-подхода. Его интеграция с CSP требует понимания того, как фреймворк генерирует и выполняет код.
Stimulus работает по паттерну HTML+JavaScript:
data-controller.data-action и
data-<controller>-target.Пример базового контроллера:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["output"]
greet() {
this.outputTarget.textContent = "Привет, мир!"
}
}
HTML для привязки:
<div data-controller="hello">
<button data-action="click->hello#greet">Сказать привет</button>
<span data-hello-target="output"></span>
</div>
Stimulus не требует инлайн-скриптов, что делает его совместимым с строгими CSP-настройками.
CSP по умолчанию блокирует inline-скрипты
(<script> без src) и
inline-события (onclick,
onchange). Stimulus полностью строится на
декларативной привязке через атрибуты, что избавляет от
необходимости использовать инлайн-обработчики.
Пример CSP-заголовка:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.jsdelivr.net;
style-src 'self' 'unsafe-inline';
connect-src 'self';
Здесь ключевым моментом является исключение
unsafe-inline для скриптов, так как Stimulus
использует модули ES и внешние файлы, а не инлайн-код. Это повышает
безопасность, исключая возможность выполнения непроверенного
JavaScript.
Stimulus рекомендуется подключать через ES-модули или сборщик (Webpack, Vite). CSP требует явного указания источников:
<script type="module" src="/js/controllers/index.js"></script>
CSP заголовок для модулей:
Content-Security-Policy:
script-src 'self' 'strict-dynamic' https://cdn.jsdelivr.net;
object-src 'none';
Использование type="module" автоматически исключает
необходимость разрешать inline-скрипты.
Некоторые библиотеки используют eval или
Function для динамического создания кода. Stimulus
не применяет eval и не создаёт код динамически, что
делает его полностью совместимым с CSP, запрещающим
'unsafe-eval':
Content-Security-Policy:
script-src 'self';
style-src 'self';
object-src 'none';
Таким образом, можно полностью запретить динамическое выполнение кода без потери функциональности Stimulus.
Stimulus поддерживает связывание событий через
data-action. Даже при генерации элементов через
Jav * aScript:
const button = document.createElement("button")
button.dataset.action = "click->hello#greet"
button.textContent = "Сказать привет"
document.body.appendChild(button)
CSP не блокирует такие действия, так как это не inline-скрипт и не использование eval.
Если Stimulus-контроллеры используют внешние библиотеки, необходимо явно разрешить их источники:
Content-Security-Policy:
script-src 'self' https://cdn.jsdelivr.net https://unpkg.com;
style-src 'self' https://fonts.googleapis.com;
Stimulus совместим с такой настройкой, так как все зависимости подключаются через внешние файлы или модули, а не через инлайн-код.
type="module" для
контроллеров.unsafe-inline для скриптов.onclick и
т.д.).script-src.'unsafe-inline' только при
использовании inline-стилей, иначе лучше подключать через
CSS-файлы.В Rails 7 с Hotwire и Stimulus CSP поддерживается по умолчанию:
app/javascript/controllers.config/initializers/content_security_policy.rb.Пример:
Rails.application.config.content_security_policy do |policy|
policy.default_src :self
policy.script_src :self, :https
policy.style_src :self, :https
end
Stimulus-контроллеры полностью работают с такой конфигурацией без использования inline-скриптов.
CSP политики в сочетании с Stimulus позволяют создать безопасное и современное веб-приложение, исключая большинство угроз, связанных с XSS, при этом сохраняя лёгкость и декларативность разработки.