vyvchy
    Теми розділу

    11 · Security для QA

    Security misconfiguration і розкриття даних

    Зміст

    Більшість глав розділу — про дефект у коді. Ця про клас, у якому коду можна не чіпати взагалі: застосунок написано правильно, тести зелені, а уже є — увімкнений дефолт, зайвий сервіс, надто балакуча сторінка помилки. Знайти таке дешево: воно видно з відповіді сервера й з налаштувань стенду. Парадокс у тому, що дешеві знахідки й лишаються незнайденими найчастіше — у релізному чеклисті їх зазвичай немає, бо «це ж не код».

    Для QA тема ближча, ніж здається: за каноном тестове середовище — це та сама конфігурація, тільки з іншими обліковими даними. Глава є каноном теми на сайті, тож межі варто назвати одразу: — глава HTTP-заголовки безпеки, CSP і клікджекінг, зовнішні сутності XML — SSRF, завантаження файлів і XXE, шифрування й TLS — Криптографія і транспорт для QA, гігієна секретів у Секрети та конфігурація в CI.

    Хибна конфігурація: вразливість без дефекту в коді

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

    У редакції :2025 категорія стоїть другою — піднялася з пʼятого місця попередньої редакції, бо в даних цього циклу хибних конфігурацій більше. Поруч цифра, що пояснює вагу теми краще за аргументи: 100% протестованих застосунків мали ту чи іншу форму хибної конфігурації, із середньою частотою 3,00% і понад 719 тисячами входжень . Провідні слабкості — CWE-16 (Configuration) і CWE-611 (некоректне обмеження зовнішньої XML-сутності).

    Ознаки категорії названо поіменно, і кожна читається як пункт перевірки:

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

    Серед сценаріїв джерело наводить показово буденний: (directory listing) не вимкнено на сервері — просто перелічує директорії.

    Запобігання сформульовано як процес: відтворюваний процес харденінгу, що дає швидко підняти ще одне належно закрите середовище; dev, QA і prod налаштовані однаково, але з різними обліковими даними; автоматизована перевірка конфігурацій в усіх середовищах, а без автоматизації — щонайменше ручна щороку. Дзеркальним випадком названо поіменно й тестові фреймворки в проді.

    «Небезпечний дефолт» тут не метафора, а стан із коробки, ще й версійний: у більшості XML-парсерів Java обробку зовнішніх сутностей увімкнено за замовчуванням, а PHP 8.0+ із дефолтним парсером блокує таку атаку сам. Відповідь на «чи вразливі ми» залежить від версії рантайму, а не від вашого коду.

    Конфігурація середовища: одинадцять тестів, а не примітка

    Конфігурацію середовища легко вважати нічиєю темою: вона виглядає розлитою по інших перевірках. У вона не розлита — (Configuration and Deployment Management Testing) стоїть другою групою тестів усередині «Web Application Security Testing», з власною нумерацією і рівно одинадцятьма пунктами. Це вже готовий чекліст стенду:

    Тест WSTGПредмет
    4.2.1Test Network Infrastructure Configurationелементи середовища
    4.2.2Test Application Platform Configurationдефолти й залишки інсталяції
    4.2.3Test File Extensions Handling for Sensitive Informationщо віддається як текст
    4.2.4Review Old Backup and Unreferenced Files for Sensitive Informationстарі копії, лістинг
    4.2.5Enumerate Infrastructure and Application Admin Interfacesадмінки й дефолтні креденшели
    4.2.6Test HTTP Methodsслужбові дієслова
    4.2.7Test HTTP Strict Transport SecurityHSTS — глава 8
    4.2.8Test RIA Cross Domain Policyфайл політики в корені
    4.2.9Test File Permissionправа на конфіги й логи
    4.2.10Test for Subdomain Takeoverмертвий DNS-запис
    4.2.11Test Cloud Storageдоступ до сховища

    Чекліст каже, що перевіряти, і не каже, яким має бути правильне значення: друге звіряють із базовими лініями або бенчмарками конфігурації (CIS-CAT Lite, Microsoft Attack Surface Analyzer, NIST National Checklist Program), причому рекомендована конфігурація різниться залежно від політики сайту й функціональності серверного ПЗ. Найдешевший артефакт теми — перелік визначених портів, потрібних застосунку, який слід вести й тримати під контролем змін: без нього критерію «зайвий порт» не існує.

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

    Дефолт платформи й залишки інсталяції

    Чому дефолт узагалі небезпечний, джерело формулює так, що знімає моралізаторство: багато різних систем зазвичай постачаються з узагальненими конфігураціями, які можуть не пасувати до завдання, що вони виконуватимуть на конкретному сайті, де їх встановлено. (application platform configuration) небезпечна не тому, що погана, а тому, що її складали без знання про ваш випадок. Тому в ревʼю дивляться, чи ввімкнено лише ті серверні модулі, які потрібні застосунку — вимкнений модуль зменшує й заразом знімає вплив вразливостей, які можуть зʼявитися в ПЗ вендора пізніше, якщо вони є лише у вже вимкнених модулях, — чи стоять власні сторінки помилок замість дефолтних і чи працює серверне ПЗ з мінімізованими привілеями. Окремий дефолт видно лише в доці платформи: файли machine.config і кореневий web.config .NET Framework за замовчуванням може читати будь-який користувач.

    Друга половина теми — (sample and known files and directories): типова інсталяція містить приклади застосунків, документацію й тестові сторінки, і все неістотне слід прибрати перед розгортанням, щоб уникнути післяінсталяційної експлуатації — саме перед, а не після знахідки. Ризик підперто чотирма реальними , у кожній з яких вразливість принесла демо-складова інсталяції, а не код застосунку. Поруч стоять ще дві перевірки того самого релізного чекліста: підтвердити, що в продакшн-середовищах не лишилося дебаг-коду чи розширень, і переглянути коментарі всередині HTML, які можуть розкрити внутрішню інформацію — інколи в коментар потрапляє й сам вихідний код. Сканер відомих файлів пошук прискорює, але єдиний спосіб бути справді впевненим — повний перегляд умісту сервера з рішенням щодо кожного файлу, чи стосується він самого застосунку.

    Адмінка: знайти її дешевше, ніж здається

    (administrator interface) дає певним користувачам виконувати привілейовані дії на сайті, і стан справ джерело описує без помʼякшень: у багатьох випадках такі інтерфейси не мають достатніх контролів, щоб захистити їх від неавторизованого доступу. Ціль тесту — виявити приховані адміністративні інтерфейси й функціональність, тобто прихованість інтерфейс з-під перевірки не виводить. Каналів пошуку кілька, і жоден не потребує експлойта: спроба вгадати шлях може бути такою простою, як запит /admin чи /administrator, а в деяких сценаріях адреса розкривається за секунди пошуковими запитами (Google dorks); перебір умісту сервера словником; посилання на адміністративну функціональність у всьому надісланому клієнту коді; конфігураційна чи довідкова документація продукту, якщо сервер розгорнуто в дефолтній конфігурації; власні дефолтні адмін-сторінки чи шляхи, які може мати кожен вебфреймворк; і навіть інший порт — адміністративний інтерфейс Apache Tomcat часто буває на порту 8080.

    Окремий вектор — підміна параметра: привілейовану функцію може вмикати GET- чи POST-параметр або змінна в кукі, а підказками названо приховані поля на кшталт <input type="hidden" name="admin" value="no">. І рідкісний випадок, коли джерело називає побічну шкоду самого тесту: перебір по знайденій адмінці має враховувати можливість блокування адміністративного облікового запису. Закривають її позитивною вимогою — харденінг, щоб адміністративні сторінки не були доступні всім, через IP-фільтрацію чи інші контролі, і перевірка, що жоден компонент не використовує чи конфігурацій. Слово «компонент» тут несуче: черга, кеш, база й брокер — кожен зі своїм постачальним акаунтом. Дефолтні креденшели (default credentials) і є найдешевшою атакою з усіх: якщо інтерфейс знайдено, слід звіритися з переліками дефолтних паролів, а вони публічні.

    Що сервер віддає, коли його не питали

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

    (unreferenced files) лежать на сервері й досяжні за адресою, хоча застосунок на них не посилається; натрапити на них і дістати важливе про інфраструктуру або облікові дані — не рідкість. Механізм витоку джерело пояснює прикладом: копія login.asp під іменем login.asp.old дозволяє качати вихідний код, бо login.asp.old типово віддається як текст, а не виконується — через своє розширення. Беруться копії з передбачуваних місць: редактори лишають file~, руки — file.old, файлова система — снапшоти, а правку файлів по місцю на файловій системі вебсервера джерело окремо називає особливо поганою звичкою, бо саме вона їх і породжує. Дістають із них облікові дані до бази в include-файлах, несилану адміністративну сторінку, яку відкриє будь-хто, хто знає, де її шукати, і стару версію з вразливістю, полагодженою у свіжішій, — тобто «баг полагоджено» і «вразливість недосяжна» це різні стани. Лікування системне: належні політики керування конфігурацією мають запобігати появі застарілих і несиланих файлів.

    Сусідній тест дивиться на ту саму механіку з іншого боку. (file extension) — те, за чим вебсервер визначає, які технології, мови й плагіни треба задіяти, щоб виконати запит, тож воно й розкриває стек; канонічний приклад витоку — файл connection.inc, пряме звернення до якого віддає його вміст. Класів два: ті, які вебсервер не має віддавати ніколи (.asa, .inc, .config), і ті, які перевіряють на те, чи вони справді мають віддаватися, а не є залишками — архіви, .java, .txt, .bak, .old. Перевірка робиться покаталожно, а саме лише розширення може бути оманливим і не є остаточним доказом.

    Доступ, який ніхто не обирав: права на файли й хмарне сховище

    Дефект тут формулюється не як «секрет лежить не там», а як ширші за потрібні (file permissions): коли ресурсу задано налаштування прав, що дає доступ ширшому діапазону , ніж потрібно, це може призвести до розкриття чутливої інформації або до зміни цього ресурсу ненавмисними сторонами. Найпоказовіший випадок — знову дефолт: значення токена для доступу до API може зберігатися в конфігураційному файлі, права на який після встановлення за замовчуванням виставлені на читання для всіх. Модель ширша за інсайдера — дані дістає й віддалений атакувальник, який скомпрометував сервіс іншими вразливостями, але отримав лише привілей звичайного користувача, тож і перевіряють від імені непривілейованого акаунта: конфігураційні файли, ключі й паролі, лог-файли, виконувані файли, тимчасові файли й каталог завантажень. Інструмент навмисно тривіальний: у Linux права перевіряють командою ls, а namei дозволяє перелічити їх рекурсивно; класифікатор — CWE-732.

    Хмарне сховище дає той самий клас із іншим , і починати варто з розвіювання ходової тези. (cloud storage misconfiguration) — це саме конфігурація, а не заводська настройка: за замовчуванням усі S3 приватні й доступні лише користувачам, яким доступ надано явно, а публічний доступ видається вручну — і на сам бакет, і на окремі обʼєкти в ньому, тож «бакет закритий» вердиктом про всі файли не є. Наслідком названо три різні знахідки — розкриття чутливої інформації, підміну даних, несанкціонований доступ. Процедура читається як звичайний негативний тест API: спершу визначити URL, за яким сервіс віддає дані, і тоді прочитати неавторизовані дані та залити новий довільний файл, причому для тестів можна взяти curl. Критерій проходження названо дослівно: правильно закритий бакет відповідає на спробу заливання помилкою AccessDenied на операції PutObject.

    Периметр без коду: піддомен, метод, файл політики

    (subdomain takeover) — вразливість, успішна експлуатація якої дозволяє супротивнику заявити права на піддомен жертви й перебрати контроль над ним. Ані код, ані сервери жертви не чіпають: потрібні дві умови разом — запис піддомену вказує на неіснуючий або неактивний ресурс чи зовнішній сервіс, і провайдер, який хостить цей ресурс, неналежно перевіряє володіння піддоменом. Уразливий не лише CNAME: перелічено A, CNAME, MX, NS, TXT та інші, і найважчий випадок саме NSзахоплення через NS-запис має найвищий вплив, бо може дати повний контроль над усією DNS-зоною й доменом жертви. Перевірка виглядає як інвентаризація: перелічити всі можливі домени — і колишні, і чинні — та виявити забуті чи неправильно налаштовані; явна ознака — коли піддомен повертає «404 — File not found», і це чітка вказівка на вразливість. Лікування — прибрати вразливий запис із зони. Механіка записів — глава DNS, IP, порти та мережа.

    Наступний пункт чекліста — методи: деякі з менш відомих методів HTTP можна вжити для лихих цілей, якщо вебсервер налаштовано хибно, а сліпа зона виникає тому, що більшості застосунків потрібні лише GET і POST, тож решту рідко враховують. Через увімкнений PUT атакувальник може покласти в систему довільний і потенційно шкідливий вміст, що веде до віддаленого виконання коду, дефейсу сайту або в обслуговуванні. OPTIONS тут вхідна точка, а не вердикт — відповідь сервера перевіряють, надсилаючи запити різними методами, зокрема довільно вигаданими на кшталт BILBAO, FOOBAR, CATS: вони показують, чи не побудований фільтр на переліку відомих дієслів. Окремо перевіряють підміну методу заголовком (X-HTTP-Method, X-HTTP-Method-Override, X-Method-Override) — інший код відповіді означає, що заборона методу на периметрі забороною не є. Історичний TRACE подано з межею, яку ставить саме джерело: у сучасних браузерах атаку можна провести лише тоді, коли застосунок інтегрується з технологіями на кшталт Flash, тож увімкнений TRACE читається як гігієна конфігурації, а не як живий експлойт. Семантика методів — глава HTTP-методи, структура, заголовки.

    Останній пункт ряду — (cross-domain policy file), який описує дозволи, з якими вебклієнт може звертатися до даних на іншому домені. Це не код застосунку: головні файли політики лежать у корені домену, і клієнт завжди спершу перевіряє головний, тож і перевірка починається звідти — спробувати отримати crossdomain.xml і clientaccesspolicy.xml із кореня застосунку і з кожної знайденої теки. Ціна помилки названа поруч: погана конфігурація таких файлів уможливлює атаки Cross-site Request Forgery і може дозволити третім сторонам дістатися чутливих даних, призначених користувачеві. Критерій оцінки вузький: запити мають надходити лише з тих доменів, портів або протоколів, які потрібні, надто дозвільних політик уникають, а політики із зірочкою розглядають особливо уважно — канонічний приклад помилки з керівництва це <allow-access-from domain="*" />.

    Помилка як розвідка

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

    Приклади витоку джерело дає буквальні: версії Struts2 і Tomcat, розкриті винятком, відрендереним користувачеві; рядок «note: The full stack trace of the root cause is available in the Apache Tomcat/7.0.56 logs»; помилка SQL-запиту разом зі шляхом установлення сайту — саме її подано як таку, що дає визначити точку .

    Редакція 2025 винесла цей клас в окрему нову категорію — A10 Mishandling of Exceptional Conditions (). Вона містить 24 CWE, серед провідних слабкостей названо CWE-209 (повідомлення про помилку з чутливою інформацією) і CWE-636 (небезпечне падіння у відкритий стан, failing open), а наслідки описано через конфіденційність, доступність і цілісність. Критерій перевірюваний: щойно застосунок не впевнений щодо своєї наступної інструкції — нештатну умову оброблено неправильно. Серед названих сценаріїв — системна помилка бази даних, показана користувачу, після якої атакувальник навмисно провокує помилки, щоб зібрати системну інформацію для точнішої , і вичерпання ресурсів, коли застосунок ловить винятки під час завантаження файлів, але не звільняє ресурси.

    Цільова поведінка сформульована парою, і саме пара є одиницею перевірки: узагальнена відповідь користувачеві, деталі — у серверний лог.

    Так

    Ні

    Неочікувана помилка

    Узагальнена відповідь
    користувачеві

    Деталі — у серверний лог

    У тілі є версія,
    шлях, фрагмент запиту?

    Витік: знахідка

    Другий бік:
    чи є запис у лозі

    Так

    Ні

    Неочікувана помилка

    Узагальнена відповідь
    користувачеві

    Деталі — у серверний лог

    У тілі є версія,
    шлях, фрагмент запиту?

    Витік: знахідка

    Другий бік:
    чи є запис у лозі

    Звідси конкретика: перекрити всі можливі режими відмови й уживати 5xx лише для запитів, які застосунок не може виконати, не даючи у відповіді вмісту, що розкриває деталі реалізації. 4xx — для запитів, що впали через помилку на боці HTTP-клієнта; 5xx — через непередбачений баг на сервері, і їх треба моніторити, бо вони добре вказують, на яких наборах даних застосунок валиться.

    Одна межа рятує від хибної цитати на співбесіді: шпаргалка Error Handling окремої вимоги «не показувати стек-трейс» не формулює — у ній заборонено віддавати вміст, що розкриває деталі реалізації. Стек- користувачеві названо ознакою вразливості в A02, а іменованою слабкістю — CWE-209 у A10.

    Запобігання A10 стисле: ловити системну помилку там, де вона виникає, плюс глобальний обробник на випадок пропущеного; обірвану відкотити цілком і почати наново (це і є failing closed); додавати ліміти — rate limiting, квоти, ; тримати обробку в одному місці.

    Перевірка з боку автотестів буденна: помилку провокують навмисно, а дивляться не на текст, а на склад відповіді.

    // Playwright: відповідь про помилку не несе деталей реалізації
    const res = await request.post('/api/orders', { data: { qty: -1 } });
    expect(res.status()).toBeGreaterThanOrEqual(400);
    
    const body = await res.text();
    for (const marker of ['at com.', 'Traceback', 'Exception in', '/var/www/', 'SQLSTATE']) {
      expect(body).not.toContain(marker);
    }

    Лог: засіб захисту, який сам є ціллю

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

    Що атакуютьЯк це виглядає
    КонфіденційністьНеавторизований доступ до чутливого в логах: персональні дані стають плацдармом для атак на цих користувачів, технічні секрети на кшталт паролів — для глибшої атаки
    ДоступністьАтакувальник заливає лог-файли, щоб вичерпати місце на диску під подальше логування
    ПідзвітністьАтакувальник спричиняє запис хибної ідентичності, щоб приховати відповідальну сторону

    Друга й третя цікаві тим, що застосунку нічого не робиться: вимкнено засіб виявлення, а не сервіс.

    Вимоги до самого логу перевіряються запитом або переглядом прав. У вебзастосунках логи не мають бути виставлені у вебдоступних місцях; якщо вже так сталося — з обмеженим доступом і з MIME-типом plain text, а не HTML. Право читати дані логів обмежують і періодично переглядають — «доступ є в усіх, хто має доступ до сервера» це невиконана вимога, а не опис норми. І відмови самої підсистеми логування не мають ні заважати роботі застосунку, ні відкривати витік: зламаний логер це два дефекти одразу, і другий помітно менш очевидний.

    Окремий сюжет — (log injection). Дані події санітизують перед записом, щоб їй запобігти: зокрема символи повернення каретки (CR), переводу рядка (LF) і символи-розділювачі. Перевірка дешева: вкласти CR/LF і розділювач у поле, яке точно логується (логін, User-Agent), і подивитися, чи зʼявився в лозі підроблений другий рядок. І ще одне, що рідко спадає на думку: саме логування джерело перевіряє як вектор відмови в обслуговуванні — його не має бути можливо використати для вичерпання ресурсів, як-от заповненням диска або перевищенням місця під журнал транзакцій бази даних.

    Персональні дані: перелік, а не інтуїція

    Питання «чи можна це писати в лог» зазвичай вирішують на око. Джерело дає два класи даних, і різниця між ними операційна.

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

    Клас 2 — корисне для розслідування, але потребує особливого поводження перед записом: шляхи файлів, внутрішні імена й адреси мережі, нечутливі персональні дані — імена людей, телефони, адреси електронної пошти. Тобто «це ж просто імʼя» аргументом за запис як є не працює.

    У першому класі стоять паролі, токени й ключі — і це інше питання, ніж маскування секретів у пайплайні: там ідеться про логи , а тут про те, чи ці значення взагалі писали в лог застосунку.

    Далі те, що в QA-практиці згадують рідко: запис сам є обробкою. Не логувати дані, якщо це не санкціоновано законом: перехоплення частини комунікацій, стеження за працівниками й збір деяких даних без згоди можуть бути незаконними. Так само не пишуться дані, від збору яких користувач відмовився або чия згода вичерпалася. А якщо особа для розбору не потрібна або ризик завеликий, застосовують (de-identification): видалення, перемішування (scrambling) або прямих і непрямих ідентифікаторів. Критерій вибору джерельний: не «як зручніше», а чи потрібна ідентичність для мети. Той самий критерій працює й у — глава Тест-дані: фабрики, фікстури, ізоляція.

    Витікають персональні дані не лише через лог. Показова механіка — IP-адреса через сторонній контент: якщо в застосунку можна вбудувати картинку із зовнішнього домену (аватар, підпис, вкладене фото), зловмисник розміщує її на своєму домені й дивиться на HTTP-запити за нею, щоб дізнатися справжню IP-адресу жертви. Та сама проблема існує в HTML-листах — і саме тому більшість поштових клієнтів блокує завантаження стороннього контенту за замовчуванням. Висновок простий: зовнішній ресурс у стрічці користувача — це перевірка приватності, а не продуктивності.

    І остання вимога, яку зазвичай не вважають перевірюваною: якщо застосунок не може запобігти зловживанню чи розкриттю чутливої інформації — зокрема логів, — правду треба сказати користувачам у ясній зрозумілій формі, щоб вони зробили поінформований вибір.

    Дефолти середовища: контейнер, порт, сокет

    «У нас у контейнері» саме собою не є ні аргументом безпеки, ні дефектом: за правильного використання контейнеризація може підвищити безпеку порівняно із запуском застосунків прямо на хості, проте певні хибні конфігурації знижують рівень безпеки або вносять нові вразливості. І варто прибрати «контейнер це маленька віртуалка»: ділять ядро хоста, тож якщо ядро хоста вразливе — вразливі й контейнери. Що таке образ і контейнер — глава Docker і тестові середовища.

    Стани з коробки, які доводиться міняти явно, джерело називає поіменно:

    • користувач — контейнер за замовчуванням працює від root, і непривілейований користувач названо найкращим способом запобігти ;
    • можливості ядра--privileged додає контейнеру ВСІ можливості ядра Linux; найбезпечніше скинути всі (--cap-drop all) і додати назад лише потрібні;
    • привілеї всередині--security-opt=no-new-privileges закриває їх здобуття через setuid/setgid-бінарники;
    • мережа між контейнерами — inter-container connectivity (icc) увімкнено за замовчуванням, тож усі контейнери спілкуються через мостову мережу docker0;
    • профіль безпеки — дефолтний профіль (seccomp, AppArmor чи SELinux) не вимикають, а беруть за базову лінію;
    • файлова система--read-only, а під тимчасові файли --tmpfs;
    • ресурси — обмеження памʼяті, CPU, дескрипторів, процесів і перезапусків названо найкращим способом уникнути відмови в обслуговуванні;
    • демона — поки не потрібно інакше, демон не запускають на рівні debug.

    Усі вісім є станами, а не сценаріями, тож перевіряються середовища, а не тестом. Окремо стоїть режим rootless: демон і контейнери під непривілейованим користувачем означають, що навіть вирвавшись із контейнера, атакувальник не отримає прав root на хості.

    Два місця заслуговують на увагу окремо. Перше — сокет демона: /var/run/docker.sock є первинною точкою входу в Docker API, власник його root, тож дати комусь доступ до сокета рівносильно наданню необмеженого root-доступу до хоста. Правило звучить як «не виставляти сокет навіть контейнерам», а монтування «лише для читання» рішенням не є — воно тільки ускладнює експлуатацію.

    Друге — опублікований порт. Поширена хибна впевненість, що правила фаєрвола захищають увесь вхідний трафік, включно з призначеним контейнерам. Насправді Docker керує власними правилами iptables і nftables напряму й обходить UFW цілком: публікація порту вставляє правила, які відкривають його на всіх інтерфейсах і для всіх адрес-джерел, і ці правила зазвичай приймаються раніше, ніж застосовуються явні DENY.

    порт опубліковано

    черга до них не доходить

    Вхідний пакет

    Власні правила Docker
    iptables / nftables

    Сервіс у контейнері

    Явні DENY
    у фаєрволі хоста

    порт опубліковано

    черга до них не доходить

    Вхідний пакет

    Власні правила Docker
    iptables / nftables

    Сервіс у контейнері

    Явні DENY
    у фаєрволі хоста

    Останнє — про секрети. Docker Secrets дає спосіб зберігати паролі, токени й SSH-ключі так, щоб уникнути їх розкриття в образах контейнерів або в командах запуску; межу ставить сама шпаргалка, і це її слова про сусідню платформу: для Kubernetes підхід не рекомендується, бо там секрети за замовчуванням зберігаються відкритим текстом. А звіти сканерів контейнерів варто читати уважно: вони виявляють три різні класи знахідок — відомі вразливості, секрети й хибні конфігурації в образах, — тож «сканер зелений» без уточнення класу не означає нічого.

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

    «Це не код — значить, не наш дефект». Виглядає як межа відповідальності, а насправді категорія описує рівно ту ситуацію, коли помилки в коді немає: ламає налаштування.

    «Стенд налаштований інакше — це нормально». Виглядає як дрібниця, а насправді канон вимагає протилежного: середовища однакові, різняться лише обліковими даними.

    «Логи пишуться — значить, із логуванням усе гаразд». Виглядає як закритий пункт, а насправді лог сам є активом: його читають, заливають до вичерпання диска й підробляють у ньому ідентичність.

    «Фаєрвол закритий, порт назовні не світиться». Виглядає як доказ, а насправді Docker пише власні правила й обходить UFW. Доказом є спроба зʼєднання ззовні, а не рядок конфігурації.

    «Адмінка не з інтерфейсу — на неї немає посилання». Виглядає як захід, а насправді ціль тесту WSTG — знайти саме приховані інтерфейси: шлях вгадують запитом /admin, дока продукту називає дефолтний, а фреймворк додає свій.

    «Бакет відкритий за замовчуванням, це дефолт хмари». Виглядає як пояснення, а насправді джерело каже протилежне: бакети приватні, а публічний доступ хтось видав вручну — на бакет або на окремий обʼєкт.

    Підсумок

    1. Хибна конфігурація — це вразливість без дефекту в коді. У редакції OWASP Top 10:2025 категорія стоїть другою, і 100% протестованих застосунків мали ту чи іншу її форму.
    2. Середовища збігаються конфігурацією й різняться обліковими даними. Ця вимога перетворює «на стенді інакше» з пояснення на знахідку.
    3. Помилка не кінець сценарію, а вхід у наступну атаку. Цільова поведінка — пара: узагальнено користувачеві, деталі в серверний лог; перевіряються обидві половини.
    4. Лог є активом і ціллю водночас. Він витікає через вебдоступне місце й зайві права — і в нього не пишуть паролів, токенів, ключів і рядків підключення.
    5. Дефолт — це стан, а не думка. root усередині контейнера, увімкнений icc, опублікований повз фаєрвол порт і змонтований сокет демона лишаються там, поки їх не прибрали явно.
    6. У конфігурації середовища є власний чекліст із одинадцяти тестів WSTG — від мережевої інфраструктури до хмарного сховища; половина знахідок цього ряду це те, що сервер віддає без запиту: лістинг каталогу, login.asp.old, .inc замість виконання, забутий піддомен із чужим 404, бакет, який приймає PutObject.

    Можливі питання

    «Що таке security misconfiguration і чим вона відрізняється від звичайного бага?» Дивляться, чи розумієте ви, що дефекту в коді може не бути взагалі. Сильна відповідь називає ознаки категорії — дефолтні акаунти, зайві можливості й порти, відсутній харденінг, надто інформативні помилки, відсутні заголовки безпеки.

    «Чому докладне повідомлення про помилку — це вразливість?» Очікують механізм, а не «бо негарно»: атака починається з розвідки, і версія сервера чи шлях установлення в тексті винятку є готовими розвідданими.

    «Як ви перевірите, що застосунок не розкриває зайвого в помилці?» Хочуть процедуру: спровокувати помилку навмисно, дивитися на склад відповіді, звірити з серверним записом про ту саму подію й закріпити перевірку автотестом.

    «Чого не можна писати в лог?» Питання-фільтр на конкретику: паролі, токени доступу, значення ідентифікації сесії, рядки підключення до бази, ключі шифрування, дані картки, чутливі персональні дані.

    «На що ви подивитесь у тестовому середовищі з погляду безпеки?» Слухають, чи не почнете ви з інструментів. Сильна відповідь називає стани: від кого працює контейнер, які порти доступні ззовні, чи не змонтований сокет демона, чи збігається конфігурація стенду з бойовою.

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

    «Як ви шукали б адмінку, якої немає в інтерфейсі?» Перевіряють, чи розумієте ви, що відсутність посилання захистом не є: ціль тесту — знайти саме приховані інтерфейси, а шлях вгадується тривіально — запит /admin, перебір словником, посилання у клієнтському коді, дефолтні шляхи фреймворка, інший порт; закриває адмінку харденінг з IP-фільтрацією і зміна дефолтних креденшелів.

    «Чому старий файл login.asp.old небезпечніший за чинний?» Дивляться на розуміння механіки: копія віддається як текст, а не виконується, тож віддає вихідний код — і може містити вразливість, уже полагоджену у свіжій версії.

    Джерела

    Хибна конфігурація: вразливість без дефекту в коді

    Конфігурація середовища: одинадцять тестів, а не примітка

    Дефолт платформи й залишки інсталяції

    • OWASP WSTG 4.2.2 — Test Application Platform Configuration — узагальнена конфігурація, пункти ревʼю, права на machine.config, службові файли інсталяції й CVE, ціль про дебаг-код, коментарі в HTML, межа сканера.

    Адмінка: знайти її дешевше, ніж здається

    Що сервер віддає, коли його не питали

    Доступ, який ніхто не обирав: права на файли й хмарне сховище

    Периметр без коду: піддомен, метод, файл політики

    Помилка як розвідка

    • OWASP Top 10:2025 — Mishandling of Exceptional Conditions — категорія й критерій «не впевнений щодо наступної інструкції», 24 CWE, CWE-209 і CWE-636, два сценарії атаки, заходи запобігання.
    • OWASP Top 10:2025 — Introduction — статус A10 як нової категорії редакції 2025.
    • OWASP Cheat Sheet — Error Handling — фаза розвідки, приклади витоку, пара «узагальнена відповідь / деталі в лог», семантика 4xx і 5xx, межа щодо стек-трейсу.

    Лог: засіб захисту, який сам є ціллю

    • OWASP Cheat Sheet — Logging — захист механізмів логування, три атаки на лог, вимоги до розміщення й прав, санітизація перед записом, логування як вектор відмови в обслуговуванні.

    Персональні дані: перелік, а не інтуїція

    • OWASP Cheat Sheet — Logging — два класи даних поіменними переліками, правова санкція як умова запису, згода, техніки знеособлення.
    • OWASP Cheat Sheet — User Privacy Protection — витік IP-адреси через сторонній контент і дефолтне блокування такого контенту, чесність перед користувачем.

    Дефолти середовища: контейнер, порт, сокет

    • OWASP Cheat Sheet — Docker Security — конфігурація проти технології, спільне ядро з хостом, дефолти рантайму й режим rootless, сокет демона як root-доступ до хоста, обхід фаєрвола опублікованим портом, Docker Secrets, три класи знахідок сканерів.

    Пояснення

    «Поясни» працює з власним API-ключем Anthropic: запит іде з вашого браузера прямо до Anthropic.

    Свій API-ключ (BYOK)

    Вставте власний ключ Anthropic — пояснення працюватиме на реальній моделі. Ключ зберігається лише у вашому браузері (localStorage), нікуди не надсилається, крім api.anthropic.com, і не логується.