Content Security Policy (CSP) определяет, какие ресурсы разрешено загружать и выполнять в браузере: скрипты, стили, изображения, шрифты и другие типы контента. При подключении UI-библиотек календаря, таких как Flatpickr, CSP становится критически важным элементом архитектуры безопасности, поскольку календарные компоненты активно взаимодействуют с DOM, создают всплывающие элементы и могут использовать динамическую генерацию стилей.
Основные директивы, влияющие на работу Flatpickr:
script-src — выполнение JavaScript-кодаstyle-src — применение CSS и inline-стилейimg-src — загрузка иконок и изображенийfont-src — подключение шрифтовconnect-src — AJAX-запросы (если используются
плагины)Flatpickr как библиотека не требует выполнения inline-скриптов после инициализации, но может конфликтовать с жёсткими CSP-политиками из-за особенностей рендеринга интерфейса.
Flatpickr генерирует DOM-структуру календаря динамически. Это означает:
document.createElementbody или
кастомный контейнерКлючевая особенность: Flatpickr не использует eval или inline
script execution, что делает его совместимым с CSP без
unsafe-eval.
Однако потенциальные точки конфликтов:
unsafe-inline в style-src (если политика
строгая)style атрибутыdata: URIFlatpickr активно использует CSS-классы, но также применяет inline-стили для позиционирования popup-календаря:
<div class="flatpickr-calendar" style="top: 120px; left: 340px;">
При строгой политике:
style-src 'self'
браузер может блокировать такие изменения, если CSP настроен на
полный запрет inline-стилей без unsafe-inline.
Решения:
style-src 'self' 'unsafe-inline' (менее
безопасно)Flatpickr обычно подключается через:
<link rel="stylesheet" href="flatpickr.min.css">
При CSP:
style-src 'self'
это работает только если файл загружается с того же домена.
При использовании CDN:
style-src 'self' https://cdn.jsdelivr.net
или аналогичный whitelist обязателен.
Некоторые темы Flatpickr используют SVG-стрелки, встроенные через CSS:
background-image: url("data:image/svg+xml,...");
При CSP:
img-src 'self'
или без разрешения data: такие элементы могут быть
заблокированы.
Корректная политика:
img-src 'self' dat a:
Инициализация Flatpickr обычно выглядит так:
flatpickr("#date", {
enableTime: true,
dateFormat: "Y-m-d"
});
Такой код безопасен при:
script-src 'self'
Проблемы возникают только если:
<script>eval в обёртках (не Flatpickr, а
интеграционный код)Рекомендуется строго разделять ресурсы:
Пример безопасной структуры:
<link rel="stylesheet" href="/assets/flatpickr.css">
<script src="/assets/app.js" defer></script>
При строгой CSP:
script-src 'self' 'nonce-abc123'
инициализация должна быть вынесена в внешний файл или снабжена nonce:
<script nonce="abc123">
flatpickr("#date");
</script>
Однако в production предпочтительнее избегать inline вообще.
Flatpickr не предоставляет полного контроля над inline positioning, но можно снизить их влияние:
static режим отображения (inline
calendar)appendToflatpickr("#date", {
appendTo: document.getElementById("calendar-container")
});
Это уменьшает необходимость динамического позиционирования через
inline top/left.
Рекомендуемая CSP-конфигурация для приложения с Flatpickr:
Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' dat a:;
font-src 'self';
Более строгий вариант (без CDN):
script-src 'self';
style-src 'self';
img-src 'self';
font-src 'self';
В этом случае Flatpickr должен быть полностью локально размещён.
Хотя Flatpickr не использует Shadow DOM по умолчанию, его поведение можно частично изолировать через:
appendTo)Пример:
flatpickr("#date", {
appendTo: document.querySelector(".calendar-root")
});
Это снижает риск пересечения CSP-ограничений с глобальным DOM.
Темы Flatpickr могут подключаться динамически:
import "flatpickr/dist/themes/dark.css";
При сборке через bundler важно:
style.insertRule без необходимостиПри строгом CSP любые динамические стили могут потребовать:
style-src 'self' 'unsafe-inline'
Flatpickr сам по себе не является источником XSS, однако опасные сценарии возникают при:
altInputonChange обработчиковonDayCreateПример потенциально опасного кода:
onDayCreate: function(dObj, dStr, fp, dayElem) {
dayElem.innerHTML = userInput;
}
CSP не заменяет санитизацию, но ограничивает последствия.
Рекомендуется:
innerHTML без очисткиtextContent вместо HTML-вставкиНекоторые опции могут косвенно влиять на CSP:
inline: true — увеличивает DOM-вставкиwrap: true — меняет структуру элементовallowInput — увеличивает поверхность взаимодействия с
пользовательским вводомЭти параметры не нарушают CSP напрямую, но увеличивают количество DOM-операций, которые могут конфликтовать с жёсткими политиками стилей.
При построении максимально строгой политики:
unsafe-inlineАрхитектура становится ближе к компонентной изоляции, где Flatpickr выступает как чистый DOM-рендерер без доступа к глобальным ресурсам кроме разрешённых CSP-директив.