Валідація вхідних даних у мобільних застосунках — основи, методи перевірки та реалізація

Автор: IT Sectr Опубліковано: 2026-04-06 Час читання: 9 хв

Валідація вхідних даних — процес перевірки вхідних даних на відповідність очікуваному формату, типу та діапазону значень перед їхньою обробкою застосунком. За даними OWASP Input Validation Cheat Sheet (2025), відсутність валідації є першопричиною більшості критичних уразливостей. Перевірка вхідних даних — перший рубіж захисту, що запобігає потраплянню некоректних або шкідливих даних у систему.

Головне

  • Валідація введення — процес перевірки даних на відповідність очікуваним форматам, типам і діапазонам перед обробкою
  • White-list vs Black-list — білий список дозволених значень завжди надійніший за чорний список заборонених
  • Серверна валідація — обов'язкова: клієнтську валідацію легко обійти, і вона не є захистом
  • Три рівні — форматна (тип/формат), семантична (значення), бізнес-валідація (логіка)
  • Санітизація — очищення даних від шкідливого вмісту, не замінює валідацію, але доповнює її

Що таке валідація вхідних даних?

Валідація вхідних даних — це перевірка того, що дані, які надходять у застосунок від користувача, зовнішнього сервісу або іншого компонента, відповідають очікуваним критеріям. Ці критерії включають тип даних (рядок, число, дата), формат (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: вона відсікає некоректні дані до того, як вони досягнуть інших компонентів системи.

Валідація vs Санітизація

Валідація відхиляє дані, що не відповідають критеріям. Санітизація (очищення) — модифікує дані, видаляючи або екрануючи небезпечні частини. Наприклад, під час введення 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% протестованих веб-застосунків покладаються виключно на клієнтську валідацію хоча б для одного поля.

Правило: клієнт — для UX, сервер — для безпеки

Клієнтська валідація може вимикати кнопку надсилання, підсвічувати помилки, показувати підказки. Серверна валідація — обов'язкова перевірка кожного параметра, навіть якщо клієнт уже перевірив його. Дублювання валідації на обох рівнях — стандартна практика. Сервер має перевіряти дані так, ніби клієнта не існує. Це гарантує захист від модифікованих запитів, автоматизованих атак і шкідливих клієнтів.

Реалізація клієнтської валідації

У вебі — HTML5-атрибути (required, pattern, min/max, type="email") і JavaScript. У мобільних застосунках — нативні валідатори текстових полів (InputFilter в Android, textField(:shouldChangeCharactersIn:) в iOS). React Hook Form і Formik для React, Vuelidate для Vue, Angular Reactive Forms — популярні бібліотеки для клієнтської валідації. Усі вони підтримують кастомні правила та асинхронну валідацію (перевірка унікальності логіна на сервері).

javascript
// Приклад серверної валідації на 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 містять докладні рекомендації щодо відображення помилок валідації.

Валідація на Android (Jetpack Compose)

Jetpack Compose пропонує декларативний підхід до валідації через state-менеджмент. Кожне поле введення прив'язане до стану (MutableState), а помилка обчислюється на основі поточного значення. Бібліотека Compose Validator спрощує створення правил: required, email, min/max length, pattern. Валідація спрацьовує при зміні тексту (onValueChange) або при спробі надсилання форми. Рекомендується показувати помилку лише після першого сабміту або після того, як користувач закінчив введення (debounce 300-500ms).

Валідація на iOS (SwiftUI)

SwiftUI не має вбудованого механізму валідації форм, але дозволяє легко реалізувати його через Combine і property wrappers. Використовуйте @State для значення поля та обчислювану властивість для помилки. Фреймворк ValidatedPropertyKit надає готові декоратори: @Validated().email(), @Validated().range(18...120). iOS-рекомендація — використовувати типи клавіатури (UIKeyboardType.emailAddress, .numberPad) і auto-capitalization для зменшення кількості помилок на рівні введення.

Валідація на Flutter

Flutter надає клас Form і TextFormField зі вбудованою валідацією через validator-колбек. Кожне поле повертає помилку як рядок або null, якщо дані коректні. FormState.validate() запускає перевірку всіх полів форми. Пакет reactive_forms для складних випадків: кастомні валідатори, асинхронна перевірка, динамічні правила. Flutter Web і мобільна версії використовують однаковий API, що спрощує підтримку.

dart
// Приклад валідації форми на 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()) {
                        // Обробити дійсні дані
                    }
                },
                child: Text('Надіслати'),
            ),
        ],
    ),
)

Техніки та інструменти валідації

Сучасні фреймворки надають вбудовані валідатори, які покривають 80% потреб. Решта 20% потребують кастомних правил, регулярних виразів або композиції наявних. Ключовий принцип — валідація має бути декларативною, щоб її можна було легко читати, тестувати та підтримувати. Уникайте валідаційної логіки, розмазаної по контролерах та екранах — виносьте її в окремі класи або схеми.

ІнструментПлатформаОсобливості
JoiNode.jsДекларативні схеми, кастомні повідомлення
PydanticPythonType hints, авто-валідація моделі
ZodTypeScriptType inference, строга типізація
javax.validationJavaBean Validation, @NotNull, @Size, @Pattern
FluentValidation.NETFluent API, rulesets, умовні правила

Підходи White-list vs Black-list

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 і може знизити конверсію форм.

  • Тільки клієнтська валідація — найнебезпечніша помилка: будь-який запит можна підробити через Postman або cURL
  • Надто суворі правила — відштовхують користувачів: OWASP рекомендує мінімум вимог під час реєстрації
  • Ігнорування Unicode — перевірка довжини рядка в байтах (а не символах) ламає російську, китайську, емодзі
  • Неінформативні помилки — «Invalid format» замість «Email must contain @ symbol after local part»
  • Перевірка на порожнє поле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-атака через валідацію?

ReDoS (Regular Expression Denial of Service) — атака, під час якої зловмисник надсилає спеціально сконструйований рядок, що спричиняє катастрофічний бектрекінг у регулярному виразі. У результаті CPU сервера завантажується на 100%, а відповідь не формується. Захист: обмеження довжини рядка, тайм-аути на regex, використання перевірених патернів.

Чи потрібно валідувати дані, отримані від бекенду?

Так, якщо дані відображаються у WebView або використовуються в HTML-контексті. Якщо бекенд скомпрометовано, дані можуть містити шкідливий код. Валідуйте та санітизуйте будь-які дані, що відображаються користувачеві, незалежно від джерела. У мобільних застосунках це особливо важливо для гібридних компонентів.

Підсумки

  • Валідація вхідних даних — обов'язковий процес перевірки вхідних даних на відповідність формату, типу та діапазону
  • White-list надійніший за Black-list — визначайте дозволені значення, а не заборонені
  • Три рівні валідації — форматна (тип/формат), семантична (логіка), бізнес-валідація (правила)
  • Серверна валідація обов'язкова — клієнтська легко обходиться і не є захистом
  • Санітизація не замінює валідацію — вони працюють у парі: валідація відхиляє, санітизація очищає
  • Інструменти — Joi, Zod, Pydantic, FluentValidation — використовуйте готові бібліотеки замість саморобних рішень
  • Тестуйте валідацію — покривайте кожне правило unit-тестами та property-based тестами

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також