Чек-лист безпеки вебзастосунків для розробників

Це практичний, готовий до аудиту чек-лист, зіставлений з рівнями верифікації 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 і видає пріоритизований звіт з усунення з доказовою базою. Замовте пентест вебзастосунку з визначеним скоупом.