Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Питання на співбесіді: OWASP і процеси безпеки

Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.

14 питань

OWASP Top 10 - перелік найкритичніших категорій ризиків вебзастосунків від некомерційної спільноти OWASP. Він складається з даних про реальні вразливості й опитування спеціалістів і оновлюється раз на кілька років. Це не стандарт і не чекліст для повної перевірки, а спільна мова й відправна точка для навчання та пріоритизації.

OWASP Top 10:2025:

  1. A01 Broken Access Control - порушення контролю доступу (чужі дані за зміненим id, відсутні перевірки прав);
  2. A02 Security Misconfiguration - помилки конфігурації (налагодження на продакшені, відкриті службові файли, стандартні паролі);
  3. A03 Software Supply Chain Failures - збої ланцюжка постачання ПЗ (вразливі й скомпрометовані залежності, збірка, CI);
  4. A04 Cryptographic Failures - криптографічні помилки (незашифровані дані, слабкі алгоритми, погане керування ключами);
  5. A05 Injection - ін'єкції (SQL, команди ОС, XSS);
  6. A06 Insecure Design - небезпечний дизайн (вразливості в самій архітектурі й логіці);
  7. A07 Authentication Failures - збої автентифікації;
  8. A08 Software or Data Integrity Failures - порушення цілісності ПЗ і даних;
  9. A09 Security Logging and Alerting Failures - збої журналювання й сповіщень;
  10. A10 Mishandling of Exceptional Conditions - неправильна обробка виняткових ситуацій.

Що помітно змінилося порівняно з 2021:

  • ланцюжок постачання став окремою широкою категорією (замість вужчої «вразливі й застарілі компоненти»);
  • неправильна конфігурація піднялася на друге місце;
  • SSRF більше не окрема категорія - увійшла до контролю доступу;
  • з'явилася нова категорія про обробку виняткових ситуацій: помилки, що «відкривають» доступ (fail-open), витоки через повідомлення про помилки;
  • у категорії журналювання акцент на сповіщеннях: недостатньо писати журнали, хтось має реагувати.

Як використовувати на практиці:

  • як основу навчання команди й пунктів рев'ю коду;
  • для пріоритизації: контроль доступу - на першому місці не випадково, його варто перевіряти в кожному ендпойнті;
  • для повнішої перевірки - OWASP ASVS (стандарт вимог до перевірки безпеки), а не лише Top 10.

Докладніше в документації: OWASP Top 10:2025

security.txt (RFC 9116) - текстовий файл за адресою /.well-known/security.txt, що повідомляє дослідникам безпеки, як повідомити про знайдену вразливість.

Без нього людина, що знайшла проблему, шукає контакти навмання: пише в загальну підтримку, в соцмережі - або не пише взагалі. Повідомлення губляться, а вразливість лишається відкритою.

Приклад:

Contact: mailto:security@example.com
Contact: https://example.com/security/report
Expires: 2027-10-01T00:00:00.000Z
Preferred-Languages: uk, en
Policy: https://example.com/security/policy
Acknowledgments: https://example.com/security/thanks
Canonical: https://example.com/.well-known/security.txt
Encryption: https://example.com/pgp-key.txt

Поля:

  • Contact (обов'язкове) - email, форма чи телефон для повідомлень; можна кілька;
  • Expires (обов'язкове) - до якої дати інформація актуальна. RFC радить не більше ніж на рік уперед - щоб застарілий файл з неробочими контактами не вводив в оману;
  • Policy - посилання на політику розкриття вразливостей: що досліджувати можна, а що ні, як ви реагуєте;
  • Preferred-Languages, Acknowledgments, Encryption (ключ для зашифрованих повідомлень), Canonical - необов'язкові.

Практичні моменти:

  • файл має бути доступний за HTTPS саме за шляхом /.well-known/security.txt. Правила вебсервера чи WAF, що блокують «приховані» шляхи, мають робити виняток для /.well-known/;
  • у Laravel - статичний файл public/.well-known/security.txt або маршрут, що генерує його з актуальною датою Expires;
  • адреса Contact має реально читатися - скринька, яку ніхто не перевіряє, гірша за її відсутність;
  • файл можна підписати OpenPGP, щоб підтвердити автентичність;
  • нагадування про оновлення Expires - інакше файл «протухне» через рік.

Це частина ширшої картини - політики розкриття вразливостей (VDP): security.txt лише вказує, куди писати, а процес реагування має існувати насправді.

Докладніше в документації: RFC 9116: security.txt

CVE (Common Vulnerabilities and Exposures) - унікальний ідентифікатор публічно відомої вразливості: CVE-2025-12345. Він дає змогу однозначно говорити про ту саму проблему в базах даних, звітах сканерів, бюлетенях вендорів. Інші екосистеми мають свої ідентифікатори: GHSA-... (GitHub Advisory Database), PKSA-... (Packagist).

CVSS (Common Vulnerability Scoring System) - оцінка серйозності від 0 до 10:

Бал Рівень
0.1-3.9 низький
4.0-6.9 середній
7.0-8.9 високий
9.0-10.0 критичний

Оцінка складається з метрик: вектор атаки (мережа чи потрібен локальний доступ), складність, потрібні привілеї, участь користувача, вплив на конфіденційність, цілісність і доступність. Актуальна версія стандарту - CVSS 4.0.

Як читати повідомлення (advisory) у залежності:

  1. чи вразлива наша версія? Діапазон уражених версій і версія з виправленням;
  2. чи використовуємо ми вразливу частину? Вразливість у функції завантаження XML не загрожує, якщо застосунок її не викликає. Але «не використовуємо» треба перевірити, а не припустити;
  3. чи досяжна вона ззовні? Вектор «мережа, без автентифікації» в публічному застосунку - найгірший випадок;
  4. чи є публічний експлойт або ознаки активної експлуатації (каталог CISA KEV) - це різко підвищує терміновість;
  5. що потрібно зробити: оновити, застосувати обхідний шлях, тимчасове правило WAF.

CVSS - не пріоритет у вашому контексті. «Критична» вразливість у бібліотеці, що використовується лише в CLI-скрипті розробника, може бути менш терміновою, ніж «середня» в публічному ендпойнті оплати. Бал - відправна точка, оцінка ризику - ваша.

Інструменти: composer audit, npm audit, Dependabot alerts, Snyk - зіставляють залежності з базами вразливостей. Важливо мати процес: хто розбирає сповіщення, у які терміни виправляються критичні й високі, як фіксується рішення «не стосується нас».

Докладніше в документації: FIRST: Common Vulnerability Scoring System

composer audit перевіряє встановлені PHP-пакети за базами відомих вразливостей (GitHub Advisory Database, Packagist) і повідомляє про уражені версії.

composer audit                 # за встановленими пакетами
composer audit --locked        # за composer.lock - зручно в CI до встановлення
composer audit --no-dev        # лише залежності продакшену
composer audit --format=json   # для автоматичної обробки

Команда повертає ненульовий код виходу, якщо є вразливості, - збірка в CI падає. Також вона повідомляє про покинуті пакети (abandoned), які більше не отримують виправлень.

npm audit - те саме для JavaScript-залежностей фронтенду:

npm audit --omit=dev           # лише залежності, що потрапляють у збірку
npm audit --audit-level=high   # падати лише на high і critical

Як вбудувати в процес:

  1. CI на кожен пул-реквест і за розкладом. Нові вразливості публікуються щодня - проєкт без змін теж може стати вразливим, тож перевірка за розкладом (щодня чи щотижня) обов'язкова;
  2. автоматичні PR оновлень - Dependabot чи Renovate створюють пул-реквести з оновленнями й security-сповіщеннями;
  3. блокування вразливих версій - сучасний Composer за замовчуванням не дає встановити через update/require версію пакета з відомою вразливістю (налаштовується в config.policy, у старіших версіях - через ключі audit);
  4. винятки - явні й з причиною: якщо вразливість не стосується проєкту, її ігнорують з поясненням і, бажано, терміном перегляду, а не вимикають перевірку повністю:
"config": {
    "policy": {
        "advisories": {
            "ignore-id": { "CVE-2026-0001": "Не використовуємо XML-парсер пакета" }
        }
    }
}

Типові помилки:

  • запуск лише вручну «колись» - фактично ніколи;
  • ігнорування npm audit, бо «там завжди щось є». Багато знахідок - у залежностях інструментів збирання (devDependencies), що не потрапляють у браузер; --omit=dev відфільтровує шум і показує те, що справді важливо;
  • оновлення лише composer.json без composer.lock - на продакшен потрапляє версія із замка.

Пам'ятати: аудит знаходить лише відомі вразливості відомих пакетів - це не захист від скомпрометованого пакета з нульового дня.

Докладніше в документації: Composer: команда audit

Персональні дані - будь-яка інформація, за якою можна ідентифікувати людину: ім'я, email, телефон, IP-адреса, ідентифікатор пристрою, геолокація, історія замовлень. Принципи GDPR (стаття 5), на які орієнтуються й українське законодавство, і більшість сучасних регуляцій:

1. Мінімізація даних - збирати лише те, що потрібно для конкретної мети. Не просити дату народження, якщо достатньо підтвердити вік; не зберігати повний номер картки, якщо потрібні останні 4 цифри.

2. Обмеження мети - дані, зібрані для доставки замовлення, не використовуються для розсилки без окремої згоди.

3. Обмеження зберігання - дані зберігаються не довше, ніж потрібно. Неактивні облікові записи, старі журнали з IP-адресами, логи запитів - видаляються чи анонімізуються за розкладом (у Laravel - Prunable/MassPrunable моделі й запланована model:prune).

4. Точність - користувач може виправити свої дані.

5. Цілісність і конфіденційність - захист від несанкціонованого доступу: шифрування, контроль доступу, журнали дій.

6. Законність і прозорість - зрозуміла політика конфіденційності, правова підстава обробки (згода, договір, законний інтерес).

Що це означає в коді:

  • права користувача: експорт своїх даних, видалення облікового запису (з даними, що за ним стоять, - включно з резервними копіями за розумний час), відкликання згоди;
  • персональні дані не потрапляють у журнали й системи моніторингу без потреби (маскування email, телефонів, токенів);
  • розділення доступу: не всі співробітники бачать усі дані; адмінка з журналом переглядів чутливих записів;
  • шифрування особливо чутливих полів (документи, медичні дані) - каст encrypted у Laravel;
  • тестові дані: не копіювати продакшен-базу з реальними людьми на ноутбуки розробників без анонімізації;
  • сторонні сервіси (аналітика, CRM, LLM) отримують лише потрібне, з договором обробки даних.

Витік персональних даних - юридична подія: GDPR вимагає повідомити наглядовий орган протягом 72 годин після виявлення, якщо витік несе ризик для людей. План дій має бути готовий заздалегідь.

Докладніше в документації: GDPR, стаття 5: принципи обробки

Моделювання загроз - систематичний пошук того, що може піти не так з безпекою, на етапі проєктування, до написання коду. Виправити дизайн на дошці дешевше, ніж переписувати готову функцію чи реагувати на інцидент.

Чотири питання (за OWASP і Адамом Шостаком):

  1. Над чим ми працюємо? - модель системи;
  2. Що може піти не так? - загрози;
  3. Що ми з цим робимо? - заходи;
  4. Чи добре ми впоралися? - перевірка.

Модель системи - діаграма потоків даних (DFD): зовнішні сутності (користувач, платіжна система), процеси (застосунок, черга), сховища (база, S3), потоки даних між ними і межі довіри - місця, де дані переходять з менш довіреної зони в більш довірену (браузер → сервер, сторонній вебхук → застосунок).

STRIDE - категорії загроз для кожного елемента діаграми:

Літера Загроза Порушена властивість Приклад
S Spoofing - підробка автентичність підроблений вебхук від «платіжної системи»
T Tampering - зміна цілісність зміна ціни в запиті оформлення замовлення
R Repudiation - заперечення неспростовність «я не змінював цей платіж» - а журналу немає
I Information disclosure - розкриття конфіденційність чужий рахунок за іншим id
D Denial of service - відмова доступність експорт без ліміту, що вантажить базу
E Elevation of privilege - підвищення прав авторизація користувач робить себе адміністратором

Приклад: нова функція «імпорт товарів з CSV за посиланням»:

  • S: хто може запускати імпорт? → лише роль менеджера;
  • T: чи можна підмінити файл між перевіркою й обробкою? → завантажити один раз і обробляти локальну копію;
  • R: хто і коли імпортував? → журнал з користувачем і файлом;
  • I: чи може URL вказувати на внутрішні ресурси (SSRF)? → перевірка URL і IP;
  • D: файл на 10 ГБ? → ліміт розміру, обробка в черзі;
  • E: CSV-ін'єкція формул при експорті назад в Excel? → екранування.

Як впровадити без бюрократії: 30-60 хвилин обговорення для функцій, що зачіпають автентифікацію, платежі, файли, зовнішні інтеграції, персональні дані; результат - перелік загроз і задач у трекері, а не документ на полиці.

Докладніше в документації: OWASP: моделювання загроз

Три класи автоматизованих перевірок безпеки шукають різне і доповнюють одне одного.

SAST (Static Application Security Testing) - аналіз вихідного коду без запуску:

  • знаходить небезпечні шаблони: конкатенацію в SQL, eval, unserialize даних користувача, виведення без екранування;
  • taint-аналіз відстежує, чи потрапляють дані з запиту ($request->input()) у небезпечні місця (DB::raw, exec) без очищення;
  • інструменти для PHP: Psalm (taint-аналіз --taint-analysis), Semgrep з правилами для PHP і Laravel, SonarQube; PHPStan з пакетами правил для частини перевірок;
  • плюси: працює рано, в PR, вказує на рядок коду;
  • мінуси: хибні спрацьовування, не бачить конфігурації й поведінки під час виконання.

DAST (Dynamic Application Security Testing) - атакує запущений застосунок ззовні, як зловмисник:

  • знаходить те, що видно лише в роботі: відсутні заголовки безпеки, відкриті службові файли, XSS і ін'єкції у відповідях, проблеми TLS, налагоджувальні сторінки;
  • інструменти: OWASP ZAP (зокрема в CI в режимі baseline scan), Burp Suite, Nuclei з шаблонами для відомих вразливостей;
  • плюси: реальна поведінка, мало хибних спрацьовувань на конфігураційних проблемах;
  • мінуси: не бачить коду, погано покриває логіку за авторизацією, повільний.

SCA (Software Composition Analysis) - аналіз залежностей:

  • зіставляє версії пакетів з базами вразливостей, перевіряє ліцензії, покинуті пакети;
  • інструменти: composer audit, npm audit, Dependabot, Renovate, Snyk, OSV-Scanner, Trivy (ще й для Docker-образів).

Чого не знайде жоден автоматичний інструмент: логічні вразливості й контроль доступу - «чи може користувач A побачити замовлення B», «чи можна оплатити замовлення за ціною 0». Для цього - тести авторизації, рев'ю коду й ручне тестування.

Практичний набір для Laravel-проєкту:

  • у кожному PR: composer audit, PHPStan/Larastan, Semgrep чи Psalm з taint-аналізом для критичних частин;
  • за розкладом: DAST (ZAP baseline) проти staging;
  • Dependabot/Renovate для оновлень;
  • тести на авторизацію для кожного ендпойнта з ідентифікатором.

Головне - реакція на результати: інструмент, звіт якого ніхто не читає, лише створює ілюзію захищеності.

Докладніше в документації: OWASP: інструменти аналізу вихідного коду

Більшість вразливостей потрапляє в код через звичайні PR. Рев'ю - найдешевше місце, щоб їх зупинити, якщо знати, куди дивитися.

1. Авторизація - перше питання до кожного нового ендпойнта:

  • чи перевіряється, що користувач має доступ саме до цього об'єкта (політика, authorize, пошук через власника)?
  • чи захищені нові методи Livewire-компонентів і дії Filament?
  • адміністративні функції - за правами, а не лише «прихована кнопка»?

2. Вхідні дані:

  • валідація з межами (довжина рядків, розмір масивів, діапазони чисел);
  • $request->validated() у create/update, а не $request->all();
  • ідентифікатори власника беруться з автентифікації, а не з тіла запиту.

3. Ін'єкції:

  • DB::raw, whereRaw, orderByRaw з даними користувача; назви колонок для сортування - з білого списку;
  • {!! !!} у Blade, v-html, dangerouslySetInnerHTML;
  • виконання команд (Process, exec), шляхи до файлів з введення користувача.

4. Дані на виході:

  • API Resource замість повернення моделі цілком;
  • чутливі поля не в журналах, відповідях і повідомленнях про помилки.

5. Секрети й конфігурація:

  • ключі в коді, тестах, прикладах конфігурації;
  • нові змінні оточення - в .env.example без значень.

6. Зовнішні взаємодії:

  • HTTP-запити за URL з введення (SSRF);
  • вебхуки - перевірка підпису;
  • завантаження файлів - тип, розмір, зберігання поза public.

7. Залежності: нові пакети - чи підтримуються, чи потрібні взагалі, скільки тягнуть за собою.

8. Обробка помилок і стану:

  • що відбувається при винятку посеред операції - чи не лишається «напіввідкритого» стану;
  • перевірки, що «пропускають» при помилці (fail-open): catch повертає true;
  • гонитва: перевірка й зміна балансу без транзакції чи блокування.

Як зробити рев'ю ефективним:

  • чекліст у шаблоні PR для змін, що торкаються автентифікації, платежів, файлів, персональних даних;
  • автоматика бере рутину (лінтери, SAST, аудит залежностей) - людина зосереджується на логіці й авторизації;
  • тести на безпеку - частина PR: «чужий користувач отримує 403» перевіряється тестом, а не на око.

Найчастіший пропуск - не ін'єкції, а відсутня перевірка прав у новому методі, що «просто повертає дані».

Докладніше в документації: OWASP Code Review Guide

Застарілі залежності - один з основних джерел вразливостей. Але бот, що щодня відкриває 30 пул-реквестів, швидко вчить команду їх ігнорувати. Мета - регулярні, невеликі, зрозумілі оновлення.

Два види оновлень:

  • security updates - негайні PR для версій з відомими вразливостями (Dependabot alerts);
  • version updates - планові оновлення до нових версій за розкладом.

Базова конфігурація Dependabot (.github/dependabot.yml):

version: 2
updates:
  - package-ecosystem: composer
    directory: /
    schedule:
      interval: weekly
    groups:
      laravel:
        patterns: ['laravel/*']
      minor-and-patch:
        update-types: [minor, patch]
    open-pull-requests-limit: 5

  - package-ecosystem: npm
    directory: /
    schedule:
      interval: weekly

  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: monthly

Що робить процес керованим:

  • групування - усі патч- і мінорні оновлення одним PR на тиждень замість десятків окремих; пов'язані пакети (laravel/*, @vue/*) - разом;
  • розклад - щотижня в певний день, коли хтось точно подивиться;
  • ліміт відкритих PR;
  • автоматичне злиття патч-оновлень, якщо проходять тести (Renovate вміє це з коробки, для Dependabot - через правила репозиторію й workflow). Без хорошого покриття тестами автозлиття небезпечне;
  • мажорні оновлення - окремо й свідомо, з читанням журналу змін.

Renovate гнучкіший: пресети конфігурації, автозлиття за правилами, «dependency dashboard» з переліком усіх доступних оновлень, затримка для щойно опублікованих версій (minimumReleaseAge).

Затримка нових версій - корисний захист від атак на ланцюжок постачання: скомпрометовані версії пакетів зазвичай виявляють і відкликають протягом днів. Оновлення на версію, опубліковану кілька днів тому, а не годину, знижує ризик.

Не забувати:

  • lock-файли (composer.lock, package-lock.json) у репозиторії - щоб продакшен отримав рівно те, що протестовано;
  • оновлення GitHub Actions і Docker-образів - теж залежності;
  • CI має запускати всі тести на PR від бота - інакше оновлення «пройде», зламавши застосунок;
  • відповідальний за розбір - інакше PR накопичуються, і за пів року оновлення стає великим і страшним.

Докладніше в документації: GitHub: оновлення версій Dependabot

Багато зламів тривають тижнями й місяцями, перш ніж їх помітять, - часто ззовні (клієнти, журналісти, дослідники). Причина - журнали або не пишуться, або пишуться, але ніхто на них не реагує. OWASP Top 10:2025 називає категорію саме «журналювання й сповіщення»: записати замало, потрібна реакція.

Які події безпеки записувати:

  • автентифікація: вдалі й невдалі входи, вихід, скидання пароля, зміна email і пароля, увімкнення/вимкнення 2FA;
  • авторизація: відмови в доступі (403), особливо серійні - ознака перебору чужих id;
  • адміністративні дії: зміна ролей і прав, видалення записів, зміна налаштувань, вхід під іншим користувачем (impersonation);
  • операції з чутливими даними: експорт, масове вивантаження, перегляд персональних даних в адмінці;
  • помилки валідації й підозрілі запити у великих кількостях;
  • платіжні операції й зміни балансу;
  • зміни API-ключів і токенів.

Що має бути в записі: час (з поясом), хто (id користувача, а не лише IP), що зроблено і з чим, звідки (IP, User-Agent), результат, ідентифікатор запиту для зв'язку з іншими журналами.

Чого не має бути: паролі, токени, повні номери карток, зайві персональні дані. Журнали - теж джерело витоків.

Захист самих журналів:

  • окреме сховище, куди застосунок лише дописує - зловмисник з доступом до сервера не повинен мати змогу стерти сліди;
  • розумний термін зберігання - і з погляду розслідувань, і з погляду захисту персональних даних;
  • захист від ін'єкцій у журнали: переноси рядків у даних користувача можуть «підробити» записи.

Сповіщення - на події, що потребують реакції:

  • сплеск невдалих входів (перебір паролів, credential stuffing);
  • вхід адміністратора з нової країни чи пристрою;
  • масовий експорт даних;
  • серія 403/404 на ресурси з ідентифікаторами;
  • зміна прав адміністратора.

У Laravel: окремий канал журналу для подій безпеки, події Login, Failed, PasswordReset з пакета автентифікації, пакет журналу дій (наприклад, spatie/laravel-activitylog) для змін моделей, відправлення в централізовану систему (SIEM, ELK, Sentry, хмарні журнали) з правилами сповіщень.

Докладніше в документації: OWASP A09:2025

Три способи знаходити вразливості руками людей - з різними цілями, вартістю й зрілістю, яку вони вимагають від команди.

Пентест (тестування на проникнення):

  • замовлена перевірка конкретної системи командою спеціалістів у визначені терміни й межі (scope);
  • результат - звіт з вразливостями, їх серйозністю й рекомендаціями;
  • плюси: глибина, перевірка бізнес-логіки, передбачувана вартість, звіт для аудиторів і клієнтів (часто вимога стандартів і корпоративних замовників);
  • мінуси: знімок на конкретний момент - наступний реліз може додати нові вразливості; результат залежить від кваліфікації конкретної команди.

VDP (Vulnerability Disclosure Policy, політика розкриття вразливостей):

  • публічна політика: як повідомити про вразливість, що дозволено досліджувати, що ні, як ви реагуєте і що не будете переслідувати дослідників, які діяли добросовісно;
  • без грошової винагороди (подяка, згадка в зали слави);
  • мінімальна вимога для будь-якої організації - разом із security.txt. Без неї люди, що випадково знайшли проблему, не знають, куди писати, і бояться юридичних наслідків.

Bug bounty:

  • VDP з грошовими винагородами залежно від серйозності, зазвичай через платформи (HackerOne, Bugcrowd, Intigriti);
  • безперервна перевірка багатьма дослідниками з різними навичками;
  • плюси: платите за результат, покриття нових релізів;
  • мінуси: потік звітів, частина з яких - дублікати й низькоякісні знахідки; потрібна команда, що швидко розбирає звіти й виправляє проблеми. Запуск bug bounty без зрілих процесів обертається завалом звітів і поганою репутацією серед дослідників.

Рекомендована послідовність зрілості:

  1. базова гігієна й автоматизовані перевірки (SAST, SCA, DAST);
  2. VDP і security.txt - канал для повідомлень;
  3. пентест перед важливими релізами й регулярно (раз на рік чи після великих змін);
  4. приватний bug bounty (запрошені дослідники), потім публічний - коли процес обробки налагоджено.

Що важливо в будь-якому варіанті:

  • чіткі межі: що можна тестувати (staging чи продакшен), що заборонено (DoS, соціальна інженерія, доступ до даних реальних користувачів);
  • терміни реакції: підтвердження отримання, оцінка, виправлення, повідомлення досліднику;
  • координоване розкриття: публікація подробиць - після виправлення, за домовленістю з дослідником.

Докладніше в документації: OWASP: розкриття вразливостей

Інцидент - не час вигадувати процес. Порядок дій, ролі й контакти мають бути визначені заздалегідь, інакше паніка коштує годин і доказів. NIST SP 800-61 Rev. 3 (2025) пов'язує реагування на інциденти із загальним керуванням кібербезпекою (CSF 2.0): підготовка, виявлення, реагування, відновлення - як безперервний цикл.

Основні кроки:

1. Виявлення й оцінка. Сповіщення моніторингу, повідомлення клієнта чи дослідника. Перше - зрозуміти масштаб: що скомпрометовано, з якого часу, чи триває атака.

2. Стримування (containment):

  • закрити вектор атаки (вимкнути вразливу функцію, правило WAF, заблокувати обліковий запис);
  • ротувати скомпрометовані секрети - ключі API, паролі до бази, APP_KEY, токени, сесії користувачів;
  • ізолювати уражені сервери, не знищуючи їх - вони потрібні для розслідування.

3. Збереження доказів: журнали, знімки дисків і пам'яті, копії підозрілих файлів - до того, як їх перезапише ротація журналів чи перевстановлення сервера. Записувати хронологію всіх дій.

4. Усунення й відновлення: виправлення вразливості, перевстановлення скомпрометованих систем з чистих образів, відновлення даних з бекапів, створених до компрометації, посилений моніторинг після повернення.

5. Повідомлення:

  • наглядовому органу - GDPR вимагає повідомити протягом 72 годин після того, як стало відомо про витік персональних даних, якщо він становить ризик для людей;
  • постраждалим людям - якщо ризик високий: що сталося, які дані, що вони можуть зробити (змінити пароль, стежити за шахрайськими листами);
  • клієнтам і партнерам - за умовами договорів;
  • юридичний відділ і, за потреби, правоохоронні органи.

6. Розбір після інциденту (post-mortem) без пошуку винних: як потрапили, чому не помітили раніше, що змінити в процесах і моніторингу. Задачі - в трекер з відповідальними.

Що підготувати заздалегідь:

  • план реагування з ролями (хто координує, хто комунікує, хто технічно розслідує) і контактами, доступний офлайн;
  • перелік секретів і процедури їх ротації;
  • журнали з достатнім терміном зберігання - без них неможливо встановити масштаб;
  • навчання - розіграш сценарію «витік бази» раз на рік показує прогалини краще за будь-який документ.

Помилки, яких варто уникати: приховувати інцидент, «тихо виправити» без розслідування масштабу, повідомляти неперевірену інформацію, знищити сервер разом із доказами.

Докладніше в документації: NIST SP 800-61 Rev. 3: реагування на інциденти

Нова категорія OWASP Top 10:2025 об'єднує вразливості, що виникають, коли система неправильно поводиться в нештатній ситуації: помилка, тайм-аут, недоступний сервіс, некоректні дані, вичерпані ресурси.

1. «Відкриття при помилці» (fail-open) - перевірка, що при збої пропускає:

function isAllowed(User $user, string $action): bool
{
    try {
        return $this->permissionService->check($user, $action);
    } catch (Throwable) {
        return true;   // «щоб не блокувати користувачів» - а насправді вимкнений контроль доступу
    }
}

Сервіс прав недоступний - і всі отримують доступ. Правильно - закриття при помилці (fail-closed): відмова й запис у журнал.

Те саме з перевіркою підпису вебхука, ліцензії, ліміту запитів, антифроду: виняток не повинен означати «перевірку пройдено».

2. Незавершені операції й неузгоджений стан. Гроші списано, а замовлення не створено; товар зарезервовано, а оплата впала. Транзакції бази, ідемпотентні операції, компенсуючі дії й узгодження (reconciliation) - щоб помилка посередині не лишала систему в стані, який можна використати.

3. Розкриття інформації через помилки: стеки викликів, SQL-запити, шляхи файлів, внутрішні адреси в повідомленнях про помилки. Користувачу - загальне повідомлення з ідентифікатором, деталі - в журнал.

4. Непередбачені стани як вектор атаки:

  • некоректні дані провокують виняток у місці, після якого пропущено перевірку;
  • різні повідомлення про помилки для «користувача не існує» і «невірний пароль» - перелік облікових записів;
  • null замість об'єкта, що трактується як «немає обмежень».

5. Виснаження ресурсів: необмежені розміри запитів, файлів, масивів, глибина рекурсії, кількість повторів - атака на доступність через «легальні», але завеликі дані.

Як захищатися:

  • закривати при помилці в усіх перевірках безпеки;
  • обробляти винятки там, де відомо, що робити, а не ковтати їх широкими catch (Throwable);
  • транзакції для операцій, що мають виконатися разом;
  • обмеження на розміри, кількості, час виконання;
  • тести негативних сценаріїв: що станеться, якщо сервіс прав, платіжний шлюз чи Redis недоступні, - і чи безпечний результат;
  • моніторинг помилок - сплеск винятків часто означає, що хтось шукає слабке місце.

Докладніше в документації: OWASP A10:2025

Перевірка безпеки «наприкінці» (пентест перед релізом) знаходить проблеми, коли їх найдорожче виправляти, і перетворює безпеку на перешкоду. Ідея shift left - вбудувати безпеку в кожен етап.

1. Вимоги й дизайн:

  • вимоги безпеки в задачах: «доступ лише власнику», «ліміт 5 спроб на хвилину», «журналювати зміну ролі» - як звичайні критерії приймання;
  • OWASP ASVS (Application Security Verification Standard, актуальна версія 5.0) - перелік перевірних вимог за рівнями: L1 для більшості застосунків, L2 для застосунків з чутливими даними, L3 для критичних систем. Зручно брати як джерело критеріїв, а не вигадувати їх щоразу;
  • моделювання загроз для функцій, що зачіпають автентифікацію, платежі, файли, персональні дані.

2. Розробка:

  • безпечні значення за замовчуванням у фреймворку й шаблонах проєкту (Laravel вже дає більшість: екранування, CSRF, підготовлені запити, хешування паролів);
  • спільні компоненти для типових задач (завантаження файлів, вебхуки, HTTP-клієнт із захистом від SSRF) - щоб кожен розробник не писав своє;
  • тести на безпеку: авторизація кожного ендпойнта, валідація, межі.

3. Перевірка в CI: SAST, аудит залежностей, сканування секретів, сканування образів - автоматично на кожен PR, з блокуванням критичних знахідок.

4. Definition of Done з пунктами безпеки: перевірено права, немає секретів у коді, нові залежності перевірено, події безпеки журналюються, документація оновлена.

5. Експлуатація: моніторинг і сповіщення, регулярні оновлення, DAST проти staging, VDP і security.txt, план реагування на інциденти.

6. Люди:

  • security champions - по одному розробнику в команді, що глибше розбирається в безпеці, стежить за практиками й є першою точкою для питань. Масштабується краще, ніж окрема команда безпеки, через яку мають проходити всі рішення;
  • навчання на реальних прикладах з власного коду й інцидентів, а не абстрактні курси;
  • культура без пошуку винних: про знайдену вразливість мають повідомляти, а не приховувати.

Як міряти: час від повідомлення про вразливість до виправлення, кількість критичних знахідок на пентестах (має зменшуватися), частка ендпойнтів з тестами авторизації, вік найстарішої необробленої вразливості в залежностях.

OWASP SAMM - модель зрілості, щоб оцінити поточний стан процесів і спланувати поступові покращення, а не все одразу.

Докладніше в документації: OWASP ASVS