Санитизация данных в контексте Pikaday заключается в обеспечении корректности, предсказуемости и безопасности всех значений, которые проходят через API календаря и взаимодействуют с DOM-элементами, форматтерами и пользовательским вводом. Основной источник рисков связан с тем, что библиотека оперирует строковыми представлениями дат, форматами отображения и внешними callback-функциями, которые могут содержать потенциально небезопасные данные.
Pikaday принимает конфигурационные параметры, среди которых ключевыми
для санитизации являются defaultDate,
setDefaultDate, minDate, maxDate,
disableDayFn, format, toString,
parse. Любое значение даты, передаваемое в эти параметры,
должно приводиться к строго определённому типу Date или
валидной строке, которая однозначно парсится.
Основная проблема возникает при передаче строк:
01-02-03)"10 января 2025")Стратегия санитизации включает явное преобразование:
function sanitizeDate(input) {
const date = new Date(input);
return isNaN(date.getTime()) ? null : date;
}
Такой подход устраняет невалидные значения до попадания в конфигурацию календаря.
Pikaday тесно связан с DOM input-элементом. Значение поля может быть изменено внешними скриптами, автозаполнением или ручным вводом. Санитизация здесь включает:
function normalizeInputValue(value) {
return value.replace(/[^\d\-\/\.]/g, '').trim();
}
После нормализации выполняется парсинг через
parse-функцию Pikaday, если она задана, либо через
стандартный конструктор Date.
Особое внимание требует параметр toString, отвечающий за
отображение даты. Если он реализован без санитизации, возможно внедрение
HTML/JS-инъекций через DOM-манипуляции.
Опасный сценарий:
toString(date) {
return `<img src=x oner ror=alert(1)>`;
}
Pikaday вставляет результат в input как строку, но при использовании сторонних UI-обёрток или кастомных рендеров это может привести к выполнению скриптов.
Безопасная реализация предполагает строго текстовый вывод:
toString(date, format) {
return date instanceof Date
? date.toISOString().split('T')[0]
: '';
}
Ключевой принцип — отсутствие HTML-разметки в возвращаемом значении.
Параметр format часто становится источником логических
уязвимостей. Хотя Pikaday не интерпретирует формат как код, некорректная
обработка может привести к:
Санитизация формата включает whitelist-подход:
const ALLOWED_TOKENS = ['DD', 'MM', 'YYYY', 'YY'];
function sanitizeFormat(format) {
return format
.split(/[^A-Za-z]/)
.filter(token => ALLOWED_TOKENS.includes(token))
.join('-');
}
Такая фильтрация устраняет произвольные строки, которые могут нарушить логику отображения.
Функция parse является одной из наиболее чувствительных
точек, поскольку позволяет полностью переопределить логику
преобразования строки в дату. Неправильная реализация может привести
к:
Корректная санитизация требует:
Dateparse(input, format) {
const parsed = customParseLogic(input, format);
if (!(parsed instanceof Date) || isNaN(parsed.getTime())) {
return null;
}
return parsed;
}
Параметры minDate и maxDate требуют строгой
проверки логической согласованности. Санитизация включает:
function sanitizeRange(minDate, maxDate) {
if (minDate && maxDate && minDate > maxDate) {
const temp = minDate;
minDate = maxDate;
maxDate = temp;
}
return { minDate, maxDate };
}
Pikaday поддерживает onSelect, onOpen,
onClose. Хотя это не данные в классическом смысле,
callback-и могут быть источником побочных эффектов, если принимают
внешние значения без проверки.
Санитизация входных аргументов callback:
onSelect(date) {
if (!(date instanceof Date) || isNaN(date.getTime())) {
return;
}
handleValidDate(date);
}
При работе с объектом конфигурации Pikaday возможны ситуации, когда передаются небезопасные объекты с изменённым прототипом. Санитизация включает создание «чистого» объекта:
function sanitizeConfig(config) {
return Object.assign(Object.create(null), config);
}
Это устраняет влияние __proto__ и предотвращает
модификацию цепочки прототипов.
Параметр i18n отвечает за строки интерфейса. Санитизация
здесь заключается в проверке структуры объекта и удалении неожиданных
ключей.
const allowedKeys = ['previousMonth', 'nextMonth', 'months', 'weekdays'];
function sanitizeI18n(i18n) {
const clean = {};
for (const key of allowedKeys) {
if (typeof i18n[key] === 'string' || Array.isArray(i18n[key])) {
clean[key] = i18n[key];
}
}
return clean;
}
Внутреннее состояние Pikaday зависит от текущей выбранной даты, отображаемого месяца и года. Санитизация состояния включает:
function sanitizeState(state) {
if (state.month < 0 || state.month > 11) state.month = 0;
if (state.year < 1970) state.year = 1970;
return state;
}
При интеграции с API или серверными источниками даты могут приходить в различных форматах. Санитизация требует унификации:
function sanitizeExternalDate(value) {
const date = new Date(value);
if (isNaN(date.getTime())) return null;
return new Date(date.toISOString());
}
Вся цепочка обработки данных в Pikaday должна строиться по принципу:
DateТакая последовательность устраняет основные классы ошибок: XSS, некорректный парсинг, нарушение диапазонов и прототипные загрязнения.