Чек-лист безпеки вебзастосунків для розробників
Це практичний, готовий до аудиту чек-лист, зіставлений з рівнями верифікації OWASP ASVS 4.0.3 та ідентифікаторами тестів WSTG, якими реально користується пентестер. Кожен пункт — конкретний контроль, який можна впровадити, побачити в дифі й протестувати в CI, а не гасло. Рухайтеся згори вниз; кожен непозначений прапорець вважайте відкритою знахідкою.
Автентифікація та управління сесіями
Збої автентифікації відповідають OWASP Top 10 A07:2021 та розділам ASVS V2 (Authentication) і V3 (Session Management). Мета — зробити крадіжку облікових даних, brute force і фіксацію сесії структурно неможливими, а не просто ускладненими. Перевіряйте кожен пункт за WSTG-ATHN і WSTG-SESS.
- Зберігайте паролі з памʼятевитратною KDF: Argon2id (≥19 MiB, t=2, p=1) або bcrypt з вартістю ≥10 / scrypt — ніколи MD5, SHA-1 чи несолений SHA-256 (ASVS V2.4).
- Вимагайте щонайменше 12 символів, дозволяйте весь діапазон Unicode і пробіли та перевіряйте нові паролі за базою витоків (API k-анонімності HIBP) — не наказуйте правил складності та примусової ротації (ASVS V2.1, NIST SP 800-63B).
- Обмежуйте частоту спроб входу з експоненційною затримкою на акаунт і на IP-адресу; повертайте ідентичні відповіді й тайминги для правильних і хибних логінів, щоб запобігти переліку користувачів (WSTG-ATHN-03).
- Генеруйте ідентифікатори сесії через CSPRNG (≥128 біт ентропії) та перегенеровуйте ідентифікатор сесії за кожної зміни привілеїв — вході, виході й step-up — щоб усунути session fixation (WSTG-SESS-03).
- Встановлюйте cookie сесії як HttpOnly, Secure та SameSite=Lax або Strict; обмежуйте їх префіксом __Host- без явного атрибута Domain (ASVS V3.4).
- Застосовуйте на боці сервера і таймаут за бездіяльністю, і абсолютний час життя сесії; анулюйте токен сесії на сервері під час виходу, а не лише на клієнті.
- Пропонуйте стійкий до фішингу MFA — WebAuthn/FIDO2 або TOTP — і ніколи SMS як єдиний другий фактор; вимагайте повторний MFA перед чутливими діями (ASVS V2.2, V2.7).
- Робіть токени скидання пароля одноразовими, короткоживучими (≤1 година), випадковими й доставленими поза основним каналом; анулюйте всі активні сесії під час зміни пароля (WSTG-ATHN-09).
Контроль доступу та авторизація
Broken Access Control — це A01:2021, ризик номер один. Більшість таких багів — логічні вади, яких не знайде жоден сканер, тож потрібні явна серверна перевірка й контроль на рівні кожного обʼєкта. Тестуйте за WSTG-ATHZ (IDOR, ескалація привілеїв, path traversal).
- Перевіряйте авторизацію на сервері для кожного запиту; за замовчуванням забороняйте й ніколи не покладайтеся на прихований елемент UI, вимкнену кнопку чи клієнтську перевірку ролі як на контроль.
- Перевіряйте володіння на рівні обʼєкта за кожного доступу — отримайте ресурс, потім підтвердіть, що автентифікований субʼєкт має право діяти з цим конкретним ID — щоб запобігти IDOR / BOLA (WSTG-ATHZ-04).
- Використовуйте непередбачувані або непрямі посилання на обʼєкти (UUIDv4 чи маппінг на користувача), але вважайте це захистом углиб, а не заміною перевірки володіння вище.
- Централізуйте авторизацію в одному шарі middleware/політик (наприклад, рушій ABAC/RBAC), а не розкидайте розрізнені if по контролерах.
- Блокуйте шляхи ескалації привілеїв: переконайтеся, що користувач не може задати собі роль, tenant_id чи прапорець is_admin через mass-assignment на ендпоінтах створення/оновлення (WSTG-ATHZ-02).
- Застосовуйте захист від CSRF на всіх запитах, що змінюють стан — синхронізувальний токен або cookie SameSite плюс валідація Origin/Referer для чутливих до cross-site дій (WSTG-SESS-05).
- Валідуйте й канонізуйте шляхи файлів та імпортовані URL, щоб заблокувати directory traversal (../) і SSRF до внутрішніх ендпоінтів метаданих на кшталт 169.254.169.254 (WSTG-ATHZ-01, A10:2021).
Валідація вводу та кодування виводу
Injection — це A03:2021. Стійке рішення — розділення коду й даних на кожній межі інтерпретатора: SQL, шелл ОС, LDAP, XML і DOM браузера. Валідуйте ввід за наміром, але реальний захист будуйте на контекстному кодуванні виводу й параметризації (WSTG-INPV).
- Використовуйте параметризовані запити / prepared statements або перевірений ORM для всього доступу до БД; ніколи не збирайте SQL конкатенацією рядків, а будь-який динамічний ідентифікатор (таблиця/колонка) перевіряйте за allowlist (WSTG-INPV-05).
- Валідуйте весь ввід за позитивним allowlist — тип, довжину, формат і діапазон — на межі довіри; де можливо, відхиляйте, а не санітизуйте (ASVS V5.1).
- Застосовуйте контекстне кодування виводу для захисту від XSS: кодування HTML-сутностей у тілі HTML, кодування атрибутів в атрибутах і кодування JavaScript/URL у їхніх контекстах — надавайте перевагу автоекранувальним шаблонізаторам (WSTG-CLNT-01).
- Уникайте виконання команд ОС з користувацьким вводом; якщо неминуче — використовуйте API з масивом аргументів (execFile, а не shell=True) і ніколи не пропускайте дані через інтерпретатор шелла (WSTG-INPV-12).
- Вимикайте розбір зовнішніх сутностей XML (XXE) у кожному парсері XML/SOAP/SVG — задайте FEATURE_SECURE_PROCESSING і забороніть DOCTYPE (A05:2021, WSTG-INPV-07).
- Відхиляйте небезпечну десеріалізацію: ніколи не десеріалізуйте недовірені дані в довільні типи; використовуйте обмежений схемою формат на кшталт JSON з явним маппінгом полів (A08:2021).
- Впровадьте серверний контроль завантаження файлів: перевіряйте тип вмісту за magic bytes, обмежуйте розмір, зберігайте поза web root і віддавайте з Content-Disposition: attachment.
- Валідуйте цілі редиректів за allowlist, щоб запобігти open redirect, застосовуваному у фішингу (WSTG-CLNT-04).
Заголовки безпеки (CSP, HSTS та інші)
Заголовки HTTP-відповідей — дешевий і високоважільний захист углиб проти XSS, клікджекінгу й пониження протоколу. Відсутність заголовків належить до A05:2021 Security Misconfiguration; перевіряйте через WSTG-CONF-07 і сканер на кшталт securityheaders.com чи Mozilla Observatory.
- Розгорніть суворий Content-Security-Policy: надавайте перевагу script-src на основі nonce або hash з 'strict-dynamic', задайте object-src 'none' і base-uri 'none', уникайте 'unsafe-inline' — викочуйте спершу через Content-Security-Policy-Report-Only.
- Встановіть Strict-Transport-Security: max-age=31536000; includeSubDomains; preload і подайте домен до списку HSTS preload, щоб заблокувати SSL-stripping.
- Надсилайте X-Content-Type-Options: nosniff у кожній відповіді, щоб зупинити MIME sniffing.
- Запобігайте клікджекінгу через frame-ancestors 'none' (або явний allowlist) у CSP; лишіть X-Frame-Options: DENY як запасний варіант для старих браузерів.
- Задайте Referrer-Policy: strict-origin-when-cross-origin, щоб не витікали повні URL (і токени в них) до третіх сторін.
- Обмежте можливості браузера через Permissions-Policy (наприклад, geolocation=(), camera=(), microphone=()) і встановіть Cross-Origin-Opener-Policy: same-origin.
- Налаштовуйте CORS явно: відображайте лише перевірені origin, ніколи не поєднуйте Access-Control-Allow-Origin: * з Allow-Credentials: true і валідуйте заголовок Origin на сервері (WSTG-CLNT-07).
Безпека залежностей і ланцюга постачання
Вразливі та застарілі компоненти — це A06:2021; тут живуть інциденти класу SolarWinds і Log4Shell. Дисципліна в тому, щоб точно знати, що ви постачаєте, перевіряти цілісність і патчити за розкладом. Орієнтуйтеся на SLSA та NIST SSDF.
- Запускайте автоматичний SCA (Dependabot, npm audit, OWASP Dependency-Check, Trivy) у CI й обривайте збірку за відомих експлуатованих (зі списку KEV) або високої критичності CVE.
- Фіксуйте залежності на точних версіях і комітьте lockfile (package-lock.json, poetry.lock, go.sum), щоб збірки були відтворюваними й верифікувалися за хешем.
- Генеруйте й зберігайте SBOM (CycloneDX або SPDX) для кожного релізу, щоб за хвилини після нового CVE відповісти на питання «чи нас це зачіпає?».
- Перевіряйте транзитивні залежності й стежте за typosquatting / dependency confusion; резервуйте імена внутрішніх пакетів і налаштуйте registry на пріоритет приватного індексу.
- Перевіряйте цілісність артефактів підписами (Sigstore/cosign) і фіксуйте сторонні GitHub Actions на повний SHA коміту, а не на змінюваний тег.
- Підпишіться на бюлетені безпеки ключових фреймворків і задайте SLA — наприклад, критичні CVE патчаться за 72 години, високі — за 7 днів.
- Видаляйте невикористовувані залежності й мертві фічі; кожен пакет, який ви не постачаєте, — це поверхня атаки, яку вам не треба захищати.
Управління секретами
Захардкоджені облікові дані — одвічна знахідка (CWE-798) і частина A05:2021. Секрети не повинні потрапляти у вихідники, образи й логи; їх слід впроваджувати під час виконання, ротувати й обмежувати мінімальними привілеями. Перевіряйте за ASVS V6 (Stored Cryptography) і V2.10 (облікові дані сервісів).
- Тримайте секрети поза системою контролю версій; скануйте репозиторій і всю історію git за допомогою gitleaks чи trufflehog і впровадьте сканер секретів у pre-commit / CI як блокувальний гейт мержу.
- Зберігайте секрети у виділеному менеджері (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager) чи зашифрованому сховищі платформи — впроваджуйте через оточення або примонтований том під час виконання, ніколи не запікайте їх в образи контейнерів.
- Ротуйте облікові дані за розкладом і негайно за підозри на витік; надавайте перевагу короткоживучим, динамічно виданим обліковим даним (dynamic secrets Vault, хмарні IAM-ролі / OIDC-федерація) над довгоживучими статичними ключами.
- Обмежуйте кожен секрет мінімальними привілеями — окремий користувач БД на сервіс лише з потрібними грантами — щоб один витік не скомпрометував усю систему.
- Ніколи не логуйте секрети, токени чи повні заголовки авторизації; додайте фільтри редагування в конвеєр логування й перевірте, що вони працюють.
- Шифруйте секрети в спокої керованим KMS і тримайте ключовий матеріал поза тією ж межею довіри, що й дані, які він захищає.
Логування, моніторинг і виявлення
Збої логування й моніторингу безпеки — це A09:2021: не можна реагувати на те, чого не бачиш. Логуйте значущі для безпеки події структуровано й у захищеному від підробки вигляді та підключайте їх до сповіщень. Перевіряйте за ASVS V7 і сигнатурами атак, виведеними з WSTG.
- Логуйте всі події автентифікації (успіх і провал), відмови контролю доступу, відхилення валідації вводу й дії адміністратора — із зазначенням хто, що, коли і звідки, у структурованому JSON (ASVS V7.1).
- Ніколи не логуйте чутливі дані — паролі, токени сесій, повні номери карток, секрети — і нейтралізуйте log injection кодуванням недовірених значень (CWE-117).
- Надсилайте логи за межі хоста до централізованого сховища лише-на-додавання (SIEM), щоб атакувальник, який захопив машину, не міг стерти сліди; зберігайте згідно з вимогами комплаєнсу.
- Сповіщайте про сигнали безпеки майже в реальному часі: сплески brute-force, серії відмов авторизації, створення нового адміна й відомі патерни атак — з маршрутом on-call.
- Включайте ID кореляції/запиту між сервісами, щоб інцидент можна було відновити end-to-end.
- Тестуйте своє виявлення: проведіть атаку (або вправу purple team) і переконайтеся, що подія справді піднімає алерт — непротестоване логування це театр.
- Синхронізуйте годинники (NTP) і записуйте позначки часу в UTC, щоб міжсистемні таймлайни були надійними під час форензики.
TLS і безпека транспорту
Cryptographic Failures — це A02:2021. Усі дані в передачі мають шифруватися сучасним, правильно налаштованим TLS; валідний сертифікат необхідний, але недостатній. Тестуйте через WSTG-CRYP-01, testssl.sh і SSL Labs, цілячись в оцінку A+.
- Віддавайте все по HTTPS і перенаправляйте HTTP на HTTPS; разом із HSTS preload не допускайте відкату на plaintext.
- Підтримуйте лише TLS 1.2 і TLS 1.3; вимкніть SSLv3, TLS 1.0 і TLS 1.1 та приберіть набори шифрів export/NULL/RC4/3DES (WSTG-CRYP-01).
- Надавайте перевагу AEAD-наборам шифрів (AES-GCM, ChaCha20-Poly1305) і вмикайте forward secrecy лише через обмін ключами ECDHE.
- Використовуйте сертифікати довіреного CA з ключем RSA ≥2048 біт або ECDSA P-256; автоматизуйте випуск і поновлення (ACME/Let's Encrypt), щоб сертифікати ніколи мовчки не спливали.
- Увімкніть OCSP stapling і розгляньте DNS-записи CAA, щоб обмежити, які CA можуть випускати сертифікати для вашого домену.
- Термінуйте TLS і для внутрішнього трафіку між сервісами (mTLS де практично) — не вважайте внутрішню мережу довіреною.
- Для нативних/мобільних клієнтів розгляньте certificate pinning і завжди перевіряйте повний ланцюг та імʼя хоста — ніколи не вимикайте перевірку «щоб запрацювало».
Головне
- ›Перевіряйте кожне рішення контролю доступу й авторизації на сервері, на рівні обʼєкта — Broken Access Control (A01) це ризик номер один, і цих логічних вад сканер за вас не знайде.
- ›Перемагайте injection (A03) параметризованими запитами й контекстним кодуванням виводу, а не фільтрацією за blocklist.
- ›Розгорніть суворий CSP на основі nonce плюс HSTS preload, X-Content-Type-Options і frame-ancestors — дешеві заголовки, що притуплюють XSS, пониження протоколу й клікджекінг.
- ›Тримайте секрети поза кодом, ротуйте їх і надавайте перевагу короткоживучим динамічно виданим обліковим даним над статичними ключами.
- ›Не можна реагувати на те, що не логуєш: структуроване, захищене від підробки логування безпеки з протестованими сповіщеннями закриває A09.
- ›Зіставляйте роботу з рівнями OWASP ASVS та ідентифікаторами тестів WSTG, щоб «безпечно» стало перевірюваним, а не декларативним.
Часті запитання
У чому різниця між OWASP ASVS і OWASP Top 10?+
Top 10 — це документ для підвищення обізнаності, що ранжує десять найкритичніших категорій ризику (наприклад, A01 Broken Access Control). ASVS — детальний тестований стандарт верифікації із сотнями конкретних вимог за трьома рівнями довіри (L1–L3). Використовуйте Top 10 для комунікації ризику, а ASVS як реальний інженерний чек-лист.
Якого рівня ASVS має досягати мій застосунок?+
Рівень 1 — мінімум для будь-якого застосунку і здебільшого перевіряється методами black-box. Рівень 2 — стандарт для застосунків із чутливими даними; більшості бізнес-застосунків варто цілитися в L2. Рівень 3 — для систем найвищої довіри (платежі, здоровʼя, критична інфраструктура) і потребує глибокого ревʼю дизайну.
Чи може чек-лист замінити пентест?+
Ні. Чек-лист запобігає відомим класам дефектів і готує вас до аудиту, але не знайде вад бізнес-логіки, ланцюгів експлойтів і специфічних для середовища помилок конфігурації. Використовуйте чек-лист для безперервного хардінгу в CI, а пентест — для незалежної перевірки того, що контролі справді витримують атаку.
Як часто запускати сканування залежностей?+
Безперервно. Вбудуйте SCA (Dependabot, Trivy, OWASP Dependency-Check) у кожен прогін CI, щоб новий код перевірявся під час коміту, і запускайте також планові скани основних гілок, щоб свіжорозкриті CVE у вже змержених залежностях ловилися навіть коли ніхто не деплоїть.
Хочете перевірити цей чек-лист на своєму робочому застосунку? MonMyIP проводить структуровану оцінку на основі ASVS/WSTG і видає пріоритизований звіт з усунення з доказовою базою. Замовте пентест вебзастосунку з визначеним скоупом.