Валидация входных данных — процесс проверки входящих данных на соответствие ожидаемому формату, типу и диапазону значений перед их обработкой приложением. По данным OWASP Input Validation Cheat Sheet (2025), отсутствие валидации является первопричиной большинства критических уязвимостей. Проверка входящих данных — первый рубеж защиты, предотвращающий попадание некорректных или вредоносных данных в систему.
Главное
Валидация входных данных — это проверка того, что данные, поступающие в приложение от пользователя, внешнего сервиса или другого компонента, соответствуют ожидаемым критериям. Эти критерии включают тип данных (строка, число, дата), формат (email, URL, телефон), диапазон значений (возраст от 18 до 120), длину (пароль от 8 до 128 символов) и допустимые символы (только латиница, цифры, дефис). Без валидации приложение может обработать данные, которые вызовут ошибки выполнения, повреждение данных или уязвимости безопасности.
Отсутствие валидации входных данных — это корневая причина таких уязвимостей, как SQL Injection, XSS, Command Injection, Path Traversal и Buffer Overflow. По данным MITRE CWE (2025), CWE-20 (Improper Input Validation) занимает второе место в рейтинге наиболее опасных программных ошибок. Валидация — это первая линия обороны в модели безопасности Defense in Depth: она отсекает некорректные данные до того, как они достигнут других компонентов системы.
Валидация отвергает данные, не соответствующие критериям. Санитизация (очистка) — модифицирует данные, удаляя или экранируя опасные части. Например, при вводе HTML-контента валидация может проверить длину текста, а санитизация — удалить script-теги через библиотеку HTML Purifier или DOMPurify. Санитизация не заменяет валидацию: они работают в паре. Валидация — политика "разрешено/запрещено", санитизация — "очищено перед использованием".
Валидация классифицируется по глубине проверки. Форматная валидация — самая простая и быстрая, бизнес-валидация — самая сложная и контекстно-зависимая. Все три уровня должны применяться последовательно: сначала формат, затем семантика, затем бизнес-логика. Пропуск любого уровня может привести к некорректной работе системы или уязвимости.
| Уровень | Что проверяет | Пример |
|---|---|---|
| Форматная | Тип данных, длина, регулярное выражение | Email содержит @, длина 5-100 |
| Семантическая | Логическая корректность значения | Дата рождения не в будущем |
| Бизнес-валидация | Соответствие бизнес-правилам | Сумма перевода не превышает баланс |
Проверка типа данных, размера, формата и допустимых символов. Реализуется через регулярные выражения, встроенные типы языков и библиотеки валидации. Примеры: проверка UUID (формат 8-4-4-4-12 шестнадцатеричных цифр), проверка номера телефона (только цифры, + в начале, от 7 до 15 символов), проверка целого числа (значение в диапазоне Integer.MIN_VALUE — Integer.MAX_VALUE). Форматная валидация — минимально необходимый уровень для любого поля ввода.
Проверка логической корректности данных в контексте предметной области. Например: дата начала не позже даты окончания, возраст в разумных пределах для системы, координаты на территории обслуживания. Семантическая валидация требует понимания бизнес-контекста и не может быть выполнена только по формату. Пример: поле "количество билетов" может пройти форматную проверку (целое число, > 0), но семантически — не может превышать количество свободных мест.
Самый сложный уровень — проверка данных на соответствие бизнес-правилам приложения. Примеры: пользователь не может удалить единственного администратора, сумма заказа не превышает кредитный лимит, товар можно заказать только если он в наличии. Бизнес-валидация часто требует запросов к базе данных или внешним сервисам и выполняется после форматной и семантической проверок. Ошибки бизнес-валидации — самые частые причины недовольства пользователей.
Клиентская валидация (в браузере или мобильном приложении) нужна для удобства пользователя: мгновенная обратная связь без отправки данных на сервер. Однако серверная валидация — единственная надёжная, поскольку клиентский код всегда можно обойти. Отправляйте запросы через инструменты разработчика, Postman или прокси (Burp Suite) — и клиентская валидация перестаёт существовать. По данным PortSwigger Research (2025), более 90% протестированных веб-приложений полагаются исключительно на клиентскую валидацию хотя бы для одного поля.
Клиентская валидация может отключать кнопку отправки, подсвечивать ошибки, показывать подсказки. Серверная валидация — обязательная проверка каждого параметра, даже если клиент уже проверил его. Дублирование валидации на обоих уровнях — стандартная практика. Сервер должен проверять данные так, будто клиента не существует. Это гарантирует защиту от модифицированных запросов, автоматизированных атак и вредоносных клиентов.
В вебе — HTML5-атрибуты (required, pattern, min/max, type="email") и JavaScript. В мобильных приложениях — нативные валидаторы текстовых полей (InputFilter в Android, textField(:shouldChangeCharactersIn:) в iOS). React Hook Form и Formik для React, Vuelidate для Vue, Angular Reactive Forms — популярные библиотеки для клиентской валидации. Все они поддерживают кастомные правила и асинхронную валидацию (проверка уникальности логина на сервере).
// Пример серверной валидации на Express с Joi
const Joi = require('joi');
const userSchema = Joi.object({
email: Joi.string()
.email()
.required()
.max(255),
age: Joi.number()
.integer()
.min(18)
.max(120)
.required(),
password: Joi.string()
.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,128}$/)
.required()
});
app.post('/api/users', async (req, res) => {
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({
error: error.details[0].message
});
}
// value — уже проверенные и безопасные данные
const user = await User.create(value);
res.status(201).json(user);
});
Мобильные приложения предъявляют особые требования к валидации данных. Экран меньше — ошибки должны быть лаконичными, клавиатура контекстной (цифровая для ввода чисел), а проверка — асинхронной, чтобы не блокировать UI. Нативные платформы предоставляют встроенные механизмы валидации, которые следует использовать по умолчанию. Material Design Guidelines для Android и Human Interface Guidelines для iOS содержат подробные рекомендации по отображению ошибок валидации.
Jetpack Compose предлагает декларативный подход к валидации через state-менеджмент. Каждое поле ввода привязано к состоянию (MutableState), а ошибка вычисляется на основе текущего значения. Библиотека Compose Validator упрощает создание правил: required, email, min/max length, pattern. Валидация срабатывает при изменении текста (onValueChange) или при попытке отправки формы. Рекомендуется показывать ошибку только после первого сабмита или после того, как пользователь закончил ввод (debounce 300-500ms).
SwiftUI не имеет встроенного механизма валидации форм, но позволяет легко реализовать его через Combine и property wrappers. Используйте @State для значения поля и вычисляемое свойство для ошибки. Фреймворк ValidatedPropertyKit предоставляет готовые декораторы: @Validated().email(), @Validated().range(18...120). iOS-рекомендация — использовать клавиатурные типы (UIKeyboardType.emailAddress, .numberPad) и auto-capitalization для снижения количества ошибок на уровне ввода.
Flutter предоставляет класс Form и TextFormField со встроенной валидацией через validator-колбэк. Каждое поле возвращает ошибку как строку или null, если данные корректны. FormState.validate() запускает проверку всех полей формы. Пакет reactive_forms для сложных случаев: кастомные валидаторы, асинхронная проверка, динамические правила. Flutter Web и мобильная версии используют одинаковый API, что упрощает поддержку.
// Пример валидации формы на Flutter
Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(labelText: 'Email'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email is required';
}
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$')
.hasMatch(value)) {
return 'Enter a valid email';
}
return null;
},
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// Process valid data
}
},
child: Text('Submit'),
),
],
),
)
Современные фреймворки предоставляют встроенные валидаторы, которые покрывают 80% потребностей. Оставшиеся 20% требуют кастомных правил, регулярных выражений или композиции существующих. Ключевой принцип — валидация должна быть декларативной, чтобы её можно было легко читать, тестировать и поддерживать. Избегайте валидационной логики, размазанной по контроллерам и экранам — выносите её в отдельные классы или схемы.
| Инструмент | Платформа | Особенности |
|---|---|---|
| Joi | Node.js | Декларативные схемы, кастомные сообщения |
| Pydantic | Python | Type hints, авто-валидация модели |
| Zod | TypeScript | Type inference, строгая типизация |
| javax.validation | Java | Bean Validation, @NotNull, @Size, @Pattern |
| FluentValidation | .NET | Fluent API, rulesets, conditional rules |
White-list (белый список) — определяете, какие данные разрешены, всё остальное отвергается. Black-list — определяете, какие данные запрещены, всё остальное пропускается. White-list всегда надёжнее: вы точно знаете, какие данные пройдут. Black-list требует предвидеть все возможные атаки, что невозможно. Пример: при проверке возраста используйте white-list (только числа от 18 до 120), а не black-list (запретить "0", "-1", "999999").
Регулярные выражения — эффективный инструмент для форматной валидации, но они могут быть источником ReDoS-атак (Regular Expression Denial of Service). Некоторые паттерны (например, (a+)+b) приводят к катастрофическому бэктрекингу на длинных строках, полностью загружая CPU сервера. Используйте проверенные regex-библиотеки и ограничивайте длину строки перед применением регулярного выражения. Для сложных случаев (email, URL) используйте встроенные парсеры языков, а не самодельные регулярки.
Даже опытные разработчики допускают ошибки при реализации валидации. Наиболее частые: валидация только на клиенте, слишком строгие правила (пароль "Must contain uppercase, lowercase, digit, special char, >= 12 chars, must not repeat characters"), неинформативные сообщения об ошибках ("Error: invalid input") и игнорирование edge-кейсов (пробелы в начале/конце, Unicode-символы, пустые строки). Каждая из этих ошибок ухудшает UX и может снизить конверсию форм.
if (value) не отличает пустую строку от нуля, false или "0"Лучшая практика — централизованная система валидации, покрытая unit-тестами. Каждое правило должно тестироваться отдельно: граничные значения, корректные данные, типовые атаки (SQLi-попытки, XSS-payloads, очень длинные строки). Регрессионные тесты на валидацию предотвращают случайное ослабление правил при рефакторинге. Используйте property-based testing (QuickCheck, fast-check) для генерации случайных данных и проверки, что валидация не падает с исключением.
Часто задаваемые вопросы
Валидация отвергает некорректные данные, а санитизация — очищает их. Например, при вводе HTML-текста валидация проверит максимальную длину, а санитизация удалит script-теги через DOMPurify. Оба процесса обязательны: валидация — для форматного контроля, санитизация — для безопасности вывода.
Нет, никогда. Клиентская валидация легко обходится через перехват и модификацию запросов. Используйте инструменты вроде Burp Suite или просто curl. Серверная валидация — единственный надёжный способ защитить систему. Клиентская валидация служит только для улучшения пользовательского опыта.
Проверяйте MIME-тип (не только расширение), размер файла, сигнатуру (магические байты в начале файла) через file signature validation. Никогда не доверяйте расширению — переименуйте файл при сохранении. Для изображений перекодируйте их серверной библиотекой (ImageMagick, Sharp), что удалит внедрённый код из EXIF-данных.
ReDoS (Regular Expression Denial of Service) — атака, при которой злоумышленник отправляет специально сконструированную строку, вызывающую катастрофический бэктрекинг в регулярном выражении. В результате CPU сервера загружается на 100%, а ответ не формируется. Защита: ограничение длины строки, тайм-ауты на regex, использование проверенных паттернов.
Да, если данные отображаются в WebView или используются в HTML-контексте. Если бэкенд скомпрометирован, данные могут содержать вредоносный код. Валидируйте и санитируйте любые данные, которые отображаются пользователю, независимо от источника. В мобильных приложениях это особенно важно для гибридных компонентов.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также