Валидацията на входни данни е процес на проверка на постъпващите данни за съответствие с очаквания формат, тип и диапазон на стойностите преди обработката им от приложението. Според OWASP Input Validation Cheat Sheet (2025) липсата на валидация е основната причина за повечето критични уязвимости. Проверката на постъпващите данни е първата линия на защита, която предотвратява проникването на некоректни или злонамерени данни в системата.
Основно
Валидацията на входни данни е проверка, че данните, които постъпват в приложението от потребителя, външна услуга или друг компонент, отговарят на очакваните критерии. Тези критерии включват тип на данните (низ, число, дата), формат (имейл, 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. Санитизацията не заменя валидацията: те работят заедно. Валидацията е политиката „разрешено/забранено“, санитизацията е „почистено преди употреба“.
Валидацията се класифицира по дълбочината на проверката. Форматната валидация е най-простата и най-бърза, а бизнес валидацията е най-сложната и най-зависима от контекста. И трите нива трябва да се прилагат последователно: първо формат, след това семантика, после бизнес логика. Пропускането на което и да е ниво може да доведе до некоректна работа на системата или уязвимости.
| Ниво | Какво проверява | Пример |
|---|---|---|
| Форматна | Тип на данните, дължина, регулярен израз | Имейлът съдържа @, дължина 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);
});
Мобилните приложения поставят специални изисквания към валидацията на данни. Екранът е по-малък — грешките трябва да са кратки, клавиатурата — контекстуална (цифрова за въвеждане на числа), а проверката — асинхронна, за да не блокира интерфейса. Вградените платформи предоставят вградени механизми за валидация, които трябва да се използват по подразбиране. Material Design Guidelines за Android и Human Interface Guidelines за iOS съдържат подробни препоръки за показване на грешки при валидация.
Jetpack Compose предлага декларативен подход към валидацията чрез управление на състоянието. Всяко поле за въвеждане е обвързано със състояние (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) и автоматичното главни букви, за да намалите броя на грешките на ниво въвеждане.
Flutter предоставя класа Form и TextFormField с вградена валидация чрез validator callback. Всяко поле връща грешка като низ или 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, условни правила |
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) водят до катастрофален backtracking върху дълги низове, напълно натоварвайки процесора на сървъра. Използвайте проверени regex библиотеки и ограничавайте дължината на низа преди прилагането на регулярния израз. За сложни случаи (имейл, URL) използвайте вградените анализатори на езиците, а не собствени регулярни изрази.
Дори опитни разработчици допускат грешки при реализацията на валидацията. Най-честите: валидация само на клиента, твърде строги правила (парола „Must contain uppercase, lowercase, digit, special char, >= 12 chars, must not repeat characters“), неинформативни съобщения за грешки ("Error: invalid input") и игнориране на крайните случаи (интервали в началото/края, 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) — атака, при която нападателят изпраща специално конструиран низ, който предизвиква катастрофален backtracking в регулярния израз. В резултат процесорът на сървъра се натоварва на 100% и отговор не се формира. Защита: ограничаване на дължината на низа, таймаути за regex, използване на проверени модели.
Да, ако данните се показват в WebView или се използват в HTML контекст. Ако бекендът е компрометиран, данните могат да съдържат злонамерен код. Валидирайте и санитизирайте всички данни, които се показват на потребителя, независимо от източника. В мобилните приложения това е особено важно за хибридните компоненти.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също