При работе с пользовательскими данными ключевая ошибка — смешивание проверки и преобразования. Библиотека validator.js изначально ориентирована на проверку строковых значений, но в реальных приложениях она часто используется вместе с этапом очистки (sanitization), который должен быть строго отделён от логики валидации.
Валидация отвечает на вопрос: соответствует ли значение ожидаемому формату. Очистка входных данных изменяет значение так, чтобы оно стало безопасным и предсказуемым для дальнейшей обработки.
Пример различия:
isEmail(value) — проверяет корректность emailnormalizeEmail(value) — приводит email к каноническому
видуСмешивание этих этапов приводит к трудноуловимым ошибкам, особенно в больших системах, где данные проходят несколько слоёв обработки.
Любой внешний ввод считается потенциально вредоносным. Это базовая модель угроз для веб-приложений:
Очистка входных данных строится на предположении, что значение может содержать:
Поэтому sanitization — это не косметическая операция, а слой безопасности и нормализации.
Перед применением любой логики данные приводятся к предсказуемому виду.
Типовые операции нормализации:
Многие функции validator.js работают только со строками, поэтому вход часто приводится явно:
const value = String(input);
import validator from 'validator';
const cleaned = validator.trim(value);
Это важно для email, логинов и URL, где пробелы могут быть незаметными, но критичными.
const normalized = value.toLowerCase();
Используется для:
Очистка не должна менять семантику данных. Например:
Пример опасной практики:
value = parseInt(value);
Если вход "0012abc", результат будет 12,
что может исказить данные.
Один из ключевых сценариев очистки — предотвращение внедрения HTML/JS.
В validator.js есть функция:
validator.escape('<script>alert(1)</script>');
Результат:
<script>alert(1)</script>
Это критично при выводе данных в HTML-контекст без дополнительного экранирования.
Важно различать:
Очистка данных строится по принципу whitelist, а не blacklist.
Удалить “плохие” символы
Разрешить только допустимые символы
Пример:
validator.whitelist(value, 'a-zA-Z0-9_');
Это снижает риск обхода фильтров, так как неизвестные символы просто не допускаются.
Email — один из самых сложных типов данных с точки зрения очистки.
validator.normalizeEmail(email, {
gmail_remove_dots: true,
gmail_remove_subaddress: true,
all_lowercase: true
});
Что происходит:
+tag)Такой подход позволяет:
Типичная ошибка — проверка до очистки или смешивание этапов.
Корректный порядок:
Пример неправильного порядка:
if (validator.isEmail(value)) {
value = validator.trim(value);
}
Здесь проверяется необработанное значение, что может привести к ложным результатам.
validator.js работает со строками, поэтому при работе с объектами требуется явная стратегия:
function sanitizeUser(user) {
return {
name: validator.escape(validator.trim(user.name || '')),
email: validator.normalizeEmail(user.email || ''),
bio: validator.escape(user.bio || '')
};
}
Особенности:
JavaScript часто приводит типы автоматически, что создаёт уязвимости.
Примеры:
null → "null"undefined → "undefined"0 → "0"Поэтому перед очисткой важно:
if (value === null || value === undefined) value = '';
value = String(value);
Очистка часто реализуется как цепочка операций:
const result = validator.escape(
validator.trim(
String(input)
)
);
Проблема такого подхода — ухудшение читаемости при росте количества шагов. В таких случаях лучше выделять функции:
function sanitize(input) {
return validator.escape(validator.trim(String(input)));
}
validator.js не предназначена для полноценной sanitization-логики. Она не покрывает:
Поэтому очистка на её основе должна дополняться:
Хорошая функция очистки должна быть идемпотентной: повторное применение не должно изменять результат.
Пример:
validator.escape('<div>')
Результат не должен снова экранироваться при повторной обработке.
Нарушение этого принципа приводит к:
Очистка входных данных должна быть согласована между:
Если хотя бы один слой допускает неочищенные данные, вся цепочка становится уязвимой.
Функции очистки должны:
Пример предпочтительного подхода:
function clean(value) {
return validator.trim(validator.escape(String(value)));
}
А не:
value.trim();
value = escape(value);
При обработке ссылок используется:
validator.isURL(value)
Но очистка URL требует осторожности:
Часто применяется комбинированный подход: проверка + нормализация + повторная проверка.
Один и тот же метод очистки может быть корректен в одном контексте и опасен в другом:
Поэтому очистка входных данных всегда привязана к месту дальнейшего использования, а не только к типу данных.