Автентифікація: атаки й тестування
Зміст
Форма входу виглядає найпростішою фічею продукту: два поля й кнопка — тому її й перевіряють найповерховіше, «правильний пароль пускає, неправильний ні». при цьому не ламає криптографію: він бере злитий на іншому сайті список пар «логін-пароль» і чекає, поки якась підійде.
Ця глава — повний виклад теми. Права після входу — Авторизація та контроль доступу, сесії й токени — Сесії та токени, самі поняття — Автентифікація та авторизація.
Збої автентифікації як категорія ризику
(Authentication Failures) в редакції 2025 означені одним реченням: присутня, коли атакувальник здатен змусити систему визнати невалідного чи неправильного користувача легітимним. Ознаки читаються як чекліст: дозволені і , які не блокуються швидко; дефолтні паролі; слабке відновлення доступу; MFA немає або вона неефективна. Причина названа прямо: більшість іде через пароль як єдиний фактор, а вимоги ротації й складності підштовхують людей вживати паролі повторно й брати слабкі.
Три атаки на пароль, які плутають
Брутфорс (brute force attack) OWASP означує ширше за «перебір паролів»: атакувальник задає наперед визначені значення, шле запити й аналізує відповідь — без розрізнюваної відповіді перебір марний. Родина розводиться за тим, що множиться:
| Атака | Що множиться | Звідки дані |
|---|---|---|
| Brute force | багато паролів проти одного акаунта | словник або клас символів |
| Credential stuffing | готові пари проти багатьох сайтів | витік чужого сайту |
| Password spraying | один слабкий пароль на багато акаунтів | список логінів |
Credential stuffing працює проти звички користувача: брутфорс вгадує, а він знає готові пари. Спроб на акаунт мало, тож детектор «багато спроб на цей логін» атаку не бачить; а з даних витоку пароль ще й скидають через (security question, KBA). — брутфорс, перепроєктований під ваш поріг: один пароль на багато акаунтів, щоб лічильник не спрацював ніколи; типова — однаковий стартовий пароль для нових користувачів, тож джерело вимагає міняти його на першому вході.
Захист спільний, головним названо MFA: за аналізом Microsoft, вона зупинила б 99,9 % компрометацій. Блокування за IP не має бути єдиним чи головним захистом — набори для credential stuffing ходять -мережами, тож обсяг на адресу низький. Для QA головне: перебору будується на тілі відповіді, а не на коді — однаковий код ще не означає однакову відповідь.
Пароль: вимоги до нього і до його зберігання
(password policy) — місце, де переказ розходиться з першоджерелом, тож числа й модальності тримаємо дослівно. NIST SP 800-63B-4 ставить SHALL на мінімум 15 символів для пароля як єдиного фактора; вісім легітимні лише як частина MFA, а максимум — SHOULD permit ... at least 64 characters.
- Композиційні правила заборонені (
SHALL NOT impose other composition rules). Єдина підстава відхилити пароль — (password blocklist), і порівнюють цілий пароль: той, хто обрав биpassword, під тиском правил береPassword1. - Планова зміна заборонена, вимушена обовʼязкова:
SHALL NOT require subscribers to change passwords periodically, алеSHALL force a changeза свідчень компрометації. - Пароль приймається цілим: задовгий має дати помилку, а не тихо вкоротитися.
І тут два канонічні джерела не збігаються. Тест-айтем -ATHN-07 оцінює політику за осями «довжина, складність, повторне використання, старіння» — тобто перевіряє те, на що NIST ставить SHALL NOT. Сам WSTG це визнає: NIST і NCSC радять проти примусового строку дії пароля, «хоча його можуть вимагати стандарти на кшталт PCI DSS». Відповідь залежить від застосовного режиму відповідності. Звідти ж обхід історії паролів: пʼять змін поспіль і повернення до початкового.
(password storage) здається темою розробника, але половина висновків робиться з інтерфейсу. Стандарт вимагає форми, resistant to offline attacks, а хеш односпрямований — тож якщо застосунок уміє показати вже збережений пароль або надіслати його листом, він тримає його у вигляді, з якого пароль дістають (показ того, що користувач друкує зараз, — інша річ, і стандарт її навпаки радить). SHA-256 непридатний через швидкість, (work factor) видно у виводі хеша, а bcrypt бере щонайбільше 72 байти — тож ліміт довжини виставляють явно. Механіка алгоритмів — тема глави «Криптографія і транспорт для QA».
Другий фактор: MFA й одноразові коди
(multifactor authentication, MFA) — вимога подати більш ніж один тип доказу. Межа проходить по типу, а не по кількості полів: пароль плюс PIN багатофакторністю не є, і те саме канон каже про пароль плюс контрольне питання. Фактори мають бути незалежні — цю умову порушує -застосунок на тому пристрої, з якого йде вхід. Причина в одному реченні: паролі не стійкі до фішингу.
Фактори канон ранжує: на основі FIDO2 — дуже надійна форма, стійка до фішингу; U2F стійкий, бо приватний ключ не покидає токен; SMS і коди телефонною мережею NIST SP 800-63B-4 позначає як (restricted authenticator). Найтонше місце — не сам фактор, а його скидання й зміна: перед зміною потрібна переавтентифікація наявним фактором, бо сесію могли захопити.
(one-time password, OTP) — теж секрет автентифікації, тож із ним поводяться за паролевою гігієною: короткий строк життя, одноразовість, суворий ліміт спроб — у шестизначного коду близько мільйона варіантів. стоїть на HMAC і лічильнику подій; TOTP — той самий HOTP, де лічильник заміняє значення, похідне від точки відліку й кроку часу (у RFC 6238 крок — системний параметр, значення за замовчуванням 30 секунд). Звідси перевірки: той самий код удруге прийматися MUST NOT; на допускається щонайбільше один крок; ліміт спроб перевіряють з паралельних сесій; код — щонайменше шість цифр.
Перелічування акаунтів: чотири виміри однакової відповіді
(account enumeration) має власний тест-айтем WSTG-IDNT-04: зібрати набір валідних логінів через механізм автентифікації. Корінь у тому, що відповідь на валідний логін відрізняється від відповіді на невалідний — часто через хибну конфігурацію або рішення дизайну, і тоді це питання до вимог, а не дефект реалізації.
Інваріант: застосунок відповідає однаковим повідомленням і однаковою довжиною на кожен невдалий вхід; еталон дослівно — «Login failed; Invalid user ID or password.» Але текст лише один вимір із чотирьох. Решта: код відповіді (200 проти 403 розрізняє акаунти, хоч сторінка однакова), довжина тіла й час — надсилання листа відновлення додає кілька сотень мілісекунд, і лікується асинхронним викликом або однаковою логікою замість «швидкого виходу».
Каналів більше, ніж форма входу: , повторне надсилання підтвердження, багатокроковий вхід (перелічування перед credential stuffing робить атаку тихішою), персональні URI, форма з контрольними питаннями — їх показують лише після підтвердження володіння поштою.
Блокування, рейт-ліміт і CAPTCHA
(account lockout) — баланс між захистом акаунта й власному користувачеві; верифікатор SHALL обмежувати невдалі спроби. Перевіряють три параметри: (lockout threshold), (observation window) і (lockout duration), яка буває й експоненційною.
Чисел-норм канон не дає: WSTG у Summary називає типовим порогом «3–5 спроб», а в Remediation — «5–10»; числа у шпаргалці OWASP стоять із e.g.. Значення беруть із вимог продукту. Лічильник привʼязується до акаунта, а не до IP-адреси, діє наскрізно по сесіях і збільшується й від невірної відповіді на контрольне питання. І головне: у блокування є зустрічний — атакувальник вашим же захистом закриває акаунти, знаючи лише логіни. Звідси розвʼязання: заблокованому дати ввійти через відновлення пароля, не блокувати акаунт самою формою відновлення, посилання розблокування робити одноразовим.
(rate limiting) у безпековому каноні ширший за HTTP-код і накладається за кількома ключами, не лише за IP. Класична помилка: кошик на пару login:<ip>:<user> заводиться на пару, тож одна адреса вичерпує поріг проти необмеженої кількості логінів — рівно та атака, яку ліміт мав спинити. Відповідь на вичерпаний ліміт канон безпеки описує інакше, ніж звикли в API-тестах: загальний 429 Too Many Requests і жодних значень Retry-After, точних настільки, щоб планувати за ними повтори. Специфікації це не суперечить — заголовок там лише MAY, — але наслідок прямий: автотест, який чекає точного Retry-After від форми логіну, перевіряє поведінку, якої канон вимагає не мати.
має три канонічні вердикти, кожен під свою модель : проти password spraying її пропонують як альтернативу блокуванню; проти автоматизованих спроб входу вона — , а не запобіжник, і блокування не заміняє; проти відмови в обслуговуванні головоломки не допомагають взагалі. Сусідні шари — й (tarpitting); для AQA це видно прямо: заповнене автоматизацією honeypot-поле ламає автотест, а тарпітинг виглядає як .
Відновлення пароля: найтихіший вектор
Відновлення пароля (forgot password) — альтернативний спосіб автентифікації, тож воно не має бути слабшим за звичайний вхід.
Форма запиту: однакове повідомлення для наявного й відсутнього акаунта — і однаковий час; не міняти стан акаунта, доки не подано валідний токен; мати ліміт на акаунт або CAPTCHA, інакше скриньку жертви заливають запитами. Токен: криптостійкий, достатньо довгий, привʼязаний до користувача, інвалідований після використання; URL не будують із заголовка Host (це Host Header Injection), а сторінка скидання ставить Referrer-Policy: no-referrer, щоб токен не витікав. Після зміни: надіслати листа, не надсилаючи пароля; не логінити автоматично; і найчастіше пропущене — інвалідувати наявні сесії, інакше пароль змінено, а стара сесія атакувальника жива.
Контрольні питання. Канон каже «ні»: за NIST SP 800-63 вони вже не є прийнятним фактором, стандарт забороняє пропонувати їх при виборі пароля (SHALL NOT), і єдиним механізмом скидання бути не можуть. Шпаргалка OWASP позначає власний статус прямо: прийнятних застосувань у безпечному ПЗ немає, поради дано для легасі — відповіді зберігають як паролі, а питання з банку не міняють, поки користувач не відповість правильно.
Відновлення доступу до MFA — той самий клас ризику: механізм потрібен, але не має ставати способом обійти MFA. А «запамʼятати мене» цю главу переростає: це Сесії та токени.
Типові помилки
- «Блокування після N невдач працює — перебір закрито» → виглядає як покритий ризик, а насправді password spraying дає одну спробу на акаунт, а credential stuffing не вгадує.
- «Пароль мусить мати велику літеру, цифру й символ» → виглядає як безпекова вимога, а насправді NIST ставить тут
SHALL NOT: вирішує режим відповідності. - «Пароль плюс контрольне питання — це 2FA» → виглядає як MFA, а фактори однотипні.
- «Повідомлення однакове — перелічування немає» → виглядає як закрита перевірка, а насправді збігтися мусять і код, і довжина, і час.
- «Пароль скинуто — акаунт у безпеці» → виглядає як завершений інцидент, а насправді старі сесії могли лишитися живими.
Підсумок
- Три атаки різняться тим, що множиться — детектор однієї не бачить інших.
- Пароль перевіряють як вимоги з модальностями, а не як «складність»; де канони розходяться, вирішує режим відповідності.
- MFA — про тип фактора, а не про кількість полів; найтонше місце — скидання й зміна фактора.
- Однакова відповідь має чотири виміри: текст, код, довжина, час.
- У кожного контролю є зустрічний ризик: блокування стає відмовою в обслуговуванні, а ліміт із хибним ключем пропускає ту саму атаку.
Можливі питання
- «Чим credential stuffing відрізняється від брутфорсу?» — брутфорс вгадує, а credential stuffing знає готові пари, тому спроб на акаунт мало й поріг блокування не спрацьовує.
- «Скільки невдалих спроб до блокування?» — пастка на число: норми немає, є три параметри й вимоги продукту.
- «Як перевірити перелічування акаунтів?» — пара «неіснуючий проти наявного» і чотири виміри порівняння.
- «Що не так із вимогою міняти пароль щокварталу?» — обидві половини вимоги NIST плюс застереження про режими відповідності.
- «Ми додали CAPTCHA. Достатньо?» — альтернатива блокуванню, глибина захисту, непридатність проти DoS.
Джерела
Збої автентифікації як категорія ризику
- OWASP Top 10:2025 — Authentication Failures — означення категорії, ознаки, .
Три атаки на пароль, які плутають
- OWASP www-community — Brute force attack — означення перебору й оракул відповіді.
- OWASP www-community — Credential stuffing — означення й місце в родині.
- OWASP www-community — Password Spraying Attack — password spraying і дефолтний пароль.
- OWASP Cheat Sheet — Credential Stuffing Prevention — означення трьох атак, межі фільтрації за IP.
- OWASP Cheat Sheet Series — Authentication — ті самі означення й оцінка MFA.
- OWASP WSTG — 4.4.3 Testing for Weak Lock Out Mechanism — блокування як засіб проти брутфорсу.
- RFC 4226 — HOTP: An HMAC-Based One-Time Password Algorithm — перебір проти короткого секрету.
Пароль: вимоги до нього і до його зберігання
- NIST SP 800-63B-4 — Digital Identity Guidelines: Authentication and Authenticator Management — довжина, композиційні правила, планова зміна.
- OWASP WSTG v4.2 — 4.4.7 Testing for Weak Password Policy (WSTG-ATHN-07) — осі тесту, історія паролів, PCI DSS.
- OWASP Cheat Sheet — Password Storage — односпрямованість, швидкі хеші, фактор роботи.
- OWASP Cheat Sheet Series — Authentication — підтвердження поточного пароля при зміні.
- OWASP Cheat Sheet — Credential Stuffing Prevention — звірка нового пароля зі злитими наборами.
Другий фактор: MFA й одноразові коди
- OWASP — Multifactor Authentication Cheat Sheet — тип фактора, ранжування, зміна фактора.
- OWASP Cheat Sheet Series — Authentication — пароль плюс контрольне питання не є MFA.
- OWASP Cheat Sheet — Choosing and Using Security Questions — обидва фактори — «щось, що ти знаєш».
- NIST SP 800-63B-4 — Digital Identity Guidelines: Authentication and Authenticator Management — паролі не стійкі до фішингу.
- RFC 4226 — HOTP: An HMAC-Based One-Time Password Algorithm — HOTP на лічильнику, довжини коду й секрету.
- RFC 6238 — TOTP: Time-Based One-Time Password Algorithm — крок 30 секунд, одноразовість, вікно .
Перелічування акаунтів: чотири виміри однакової відповіді
- OWASP WSTG — 4.3.4 Testing for Account Enumeration and Guessable User Account — мета тесту, однакові повідомлення, канали.
- OWASP Cheat Sheet Series — Authentication — еталон повідомлення й код відповіді як канал.
- OWASP Cheat Sheet — Forgot Password — однакове повідомлення й однаковий час.
- OWASP Cheat Sheet — Credential Stuffing Prevention — багатокроковий вхід і перелічування.
- OWASP Cheat Sheet — Choosing and Using Security Questions — питання лише після підтвердження пошти.
Блокування, рейт-ліміт і CAPTCHA
- OWASP WSTG — 4.4.3 Testing for Weak Lock Out Mechanism — компроміс блокування, розбіжність порогів, розблокування.
- OWASP Cheat Sheet Series — Authentication — три параметри політики й ризик DoS.
- NIST SP 800-63B-4 — Digital Identity Guidelines: Authentication and Authenticator Management — вимога обмежувати невдалі спроби.
- OWASP Cheat Sheet — Denial of Service — означення ліміту й блокування як DoS.
- OWASP Cheat Sheet — Bot Management and Anti-Automation — ключі ліміту, кошик «IP плюс логін», honeypot.
- OWASP Cheat Sheet — Forgot Password — заборона блокувати акаунт через відновлення.
- OWASP Cheat Sheet — Choosing and Using Security Questions — невірна відповідь як невдала спроба.
- RFC 4226 — HOTP: An HMAC-Based One-Time Password Algorithm — блокування наскрізно по сесіях.
- OWASP Cheat Sheet — Credential Stuffing Prevention — обхід ліміту за IP проксі-мережами.
- OWASP www-community — Password Spraying Attack — CAPTCHA як альтернатива блокуванню.
- RFC 6585 — Additional HTTP Status Codes —
Retry-Afterпри429лишеMAY.
Відновлення пароля: найтихіший вектор
- OWASP Cheat Sheet — Forgot Password — форма запиту, токен, дії після зміни.
- OWASP Cheat Sheet — Choosing and Using Security Questions — статус контрольних питань і правила для легасі.
- NIST SP 800-63B-4 — Digital Identity Guidelines: Authentication and Authenticator Management — заборона пропонувати контрольні питання.
- OWASP www-community — Credential stuffing — витік як шлях до скидання пароля.
- OWASP — Multifactor Authentication Cheat Sheet — відновлення доступу до MFA.
- OWASP WSTG — 4.3.4 Testing for Account Enumeration and Guessable User Account — часовий канал витоку через лист.
Що таке збої автентифікації як категорія ризику і за якими ознаками їх шукають?
Категорія описує один результат: систему вдалося переконати, що перед нею легітимний користувач, хоча це не так — саме так її формулює редакції 2025. Ознаки зручно читати як перелік перевірок: перебір і зі злитими парами ніхто не спиняє швидко, у продукті лишилися дефолтні паролі, відновлення доступу слабше за звичайний вхід, другого фактора немає або він неефективний. Корінь названо без делікатності — пароль як єдиний доказ, а вимоги «міняй щокварталу, додай спецсимвол» дають зворотний ефект: люди беруть слабші паролі й вживають їх повторно. Практичний висновок для QA: перевіряти треба не «правильний пароль пускає, неправильний ні», а механізми навколо форми — лічильники, повідомлення, ліміти, флоу відновлення. Більшість перевірок тут не про криптографію, а про логіку й конфігурацію, тож вони цілком доступні функціональному тестувальнику без пентестерського інструментарію.
Чим брутфорс відрізняється від credential stuffing?
Різниця в тому, звідки береться пароль: перебір його вгадує, credential stuffing уже його має. Класичний б'є багатьма паролями в один акаунт — зі словника або перебором класу символів; credential stuffing бере готові пари «логін-пароль» з витоку чужого сервісу й розкидає їх по багатьох сайтах, розраховуючи на людську звичку вживати один пароль скрізь. Наслідок для детекторів прямий: у credential stuffing спроб на конкретний акаунт мало (часто одна), тому лічильник «забагато невдач на цей логін» її просто не бачить. Гірше того, злитих даних інколи вистачає не для входу, а для скидання пароля через — тобто може обійти форму логіну взагалі. На співбесіді варто додати означення перебору з канону: він не зводиться до паролів, це надсилання наперед визначених значень з аналізом відповіді, і без розрізнюваної відповіді перебір безсилий.
Що таке password spraying і чому поріг блокування його не ловить?
Це перебір, перепроєктований під ваш власний захист: замість багатьох паролів в один акаунт бере один поширений пароль і проганяє його по великому списку логінів. На кожен акаунт припадає одна спроба, тож лічильник невдач ніколи не доходить до порога, а прогін виглядає як фоновий шум із невдалих входів у різних користувачів. Типова успіху — однаковий стартовий пароль для нових співробітників чи клієнтів; звідси й вимога канону змушувати міняти його на першому вході. Захист тут інший, ніж від брутфорсу: лічильника на акаунт замало, потрібні ліміти за кількома ключами, а не лише за IP, як альтернатива блокуванню й, головне, другий фактор. Найкорисніша фраза у відповіді: три атаки різняться тим, що саме множиться, тому детектор, налаштований на одну, спокійно пропускає дві інші.
Чому фільтрацію за IP не роблять головним захистом від credential stuffing?
Тому що атакувальник платить за обхід цього фільтра копійки. Готові набори для credential stuffing ходять через -мережі, тож на кожну окрему адресу припадає низький обсяг запитів — рівно такий, що під поріг не підпадає. Канон формулює це прямо: блокування за адресою не повинно бути єдиним чи головним засобом, воно лишається одним із шарів. Додатковий аргумент — зустрічний збиток: ціль канон формулює як «підняти вартість зловживання, не зачепивши легітимних користувачів», а поріг за самою лише адресою б'є і по них. Тому ліміт заводять за кількома ключами водночас, а не лише за адресою, а першою лінією проти цієї атаки називають MFA — за оцінкою Microsoft, яку наводить канон, вона зупинила б 99,9 % компрометацій.
Скільки невдалих спроб має бути до блокування акаунта?
Це питання-пастка: нормативної цифри немає, і сильна відповідь починається саме з цього. Канон дає не число, а три параметри, які треба назвати: , , протягом якого спроби рахуються, і , яка може ще й зростати експоненційно. Самі числа в джерелах плавають — той самий тест-айтем в одному місці називає типовим діапазон три-пʼять спроб, а в рекомендаціях уже пʼять-десять, а у шпаргалках OWASP цифри стоять із позначкою «наприклад». Отже, конкретні значення беруться з вимог продукту й моделі , а тест перевіряє відповідність цим вимогам, а не абстрактній «правильній» цифрі. Корисно додати деталі механіки: лічильник вішають на акаунт, а не на IP-адресу, він працює наскрізно по всіх сесіях і збільшується також від невірної відповіді на контрольне питання.
Ми ввімкнули блокування після невдалих спроб. Який ризик ми щойно створили?
в обслуговуванні власним користувачам — і створює її атакувальник вашими ж руками. Знаючи лише перелік логінів (а їх часто дає ), він шле по кілька завідомо невірних паролів на кожен і закриває акаунти масово, не маючи жодного шансу ввійти. Тому блокування — це завжди компроміс між захистом акаунта й доступністю, і його налаштування має враховувати обидві сторони: чим агресивніший поріг, тим дешевша атака на доступність. Розвʼязання канон описує так: заблокованому лишають дорогу назад через , сама форма відновлення акаунт не блокує, а посилання на розблокування робиться одноразовим. Для тесту це три окремі сценарії, і найчастіше пропускають саме останній — багаторазове посилання розблокування живе в пошті місяцями.
Яку довжину пароля вимагати і чи потрібні великі літери, цифри й символи?
За NIST SP 800-63B-4 пароль, який працює єдиним фактором, має бути щонайменше 15 символів (модальність SHALL); вісім символів лишаються легітимними тільки як частина MFA, а приймати верифікатор SHOULD дозволяти щонайменше 64 символи. Композиційні правила стандарт забороняє прямо (SHALL NOT), і логіка тут не в лібералізмі: людина, яка сама обрала б password, під тиском правил вибере Password1 — ентропії не додалося, зручність зникла. Єдина дозволена підстава відхилити пароль — блоклист відомих і злитих паролів, причому порівнювати треба цілий пароль, а не шматки. Ще одна вимога, яку легко перевірити з інтерфейсу: задовгий пароль має дати чесну помилку, а не тихо вкоротитися до N символів, бо тоді користувач думає, що має довгий секрет, а насправді ні. І окремо — застереження про режим відповідності: якщо продукт живе під стандартом на кшталт PCI DSS, вимоги до складності й строку дії пароля можуть розходитися з NIST, і вирішує тут застосовний режим, а не смак команди.
Чим погана вимога міняти пароль раз на квартал?
Тим, що вона знижує якість паролів і не додає захисту в обмін. Стандарт NIST забороняє вимагати планову зміну (SHALL NOT), але тим самим документом зобовʼязує змусити змінити пароль, коли є свідчення компрометації — тобто половинки вимоги легко переплутати й відповісти неправильно. Той самий документ пояснює, чому саме: ротацію привʼязують до події — витоку, виявленої компрометації, зміни технології автентифікатора, — а не до календаря. Тут же живе класичний обхід історії паролів: пʼять швидких змін поспіль — і можна повернути початковий, тож тест на «історію» без обмеження частоти змін нічого не гарантує. Важливе застереження для співбесіди: тест-айтем WSTG досі оцінює політику за осями складності й строку дії, бо цього можуть вимагати стандарти відповідності — тобто відповідь «NIST забороняє, тому це баг» неповна, вирішує застосовний до продукту режим.
Як тестувальник з боку інтерфейсу розуміє, що паролі зберігають небезпечно?
Головний — здатність системи показати вам ваш уже збережений пароль або надіслати його листом. Хеш односпрямований, з нього пароль не дістати, тож якщо продукт це вміє, він тримає пароль у відновлюваній формі — і на цьому висновок робиться без доступу до бази. Не плутайте з кнопкою «показати пароль» у самому полі вводу: показ того, що людина друкує зараз, канон навпаки вважає корисним для зручності. Друга група сигналів — непрямі: мовчазне обрізання довгого пароля натякає на ліміт алгоритму (bcrypt бере щонайбільше 72 байти, тож обмеження мало б стояти явно і з повідомленням). Сам алгоритм лишається питанням до розробника: швидкий хеш на кшталт SHA-256 непридатний саме через швидкість, а видно у виводі хеша. Третє — процес: зміна пароля має вимагати підтвердження поточного, а лист після скидання не має містити самого пароля. Усе це заводиться як окремі знахідки з посиланням на канон, а не як «мені здається, там небезпечно».
Пароль плюс контрольне питання — це двофакторна автентифікація?
Ні, і причина не в кількості екранів, а в типі доказу: багатофакторність вимагає доказів різних типів, а пароль і відповідь на контрольне питання — це двічі «щось, що ти знаєш». З тієї самої причини не є MFA пароль плюс PIN, хоча полів у формі два. Ще одна умова, яку в продуктах ламають частіше за визначення, — незалежність факторів: -застосунок на тому самому телефоні, з якого людина й логіниться, дає другий тип доказу, але компрометація одного пристрою знімає обидва. Канон іще й ранжує фактори: на базі FIDO2 стійкий до фішингу, U2F надійний тим, що приватний ключ не покидає токен, а коди через телефонну мережу NIST позначає як . І найвразливіше тут не сам фактор, а процедура його заміни чи скидання: змінювати другий фактор можна лише після повторного підтвердження особи тим, що вже налаштоване, інакше захоплена сесія спокійно переписує MFA на себе.
Чим HOTP відрізняється від TOTP і які перевірки з цього ростуть?
Обидва — той самий алгоритм на HMAC, різниця лише в тому, що подається лічильником. У це лічильник подій: код живе, доки його не використали або доки лічильник не зсунувся. У TOTP лічильник замінює величина, похідна від точки відліку й кроку часу, і RFC 6238 рекомендує крок у 30 секунд — звідси й ефект «код змінюється кожні пів хвилини». — такий самий секрет автентифікації, як пароль, тож із нього ростуть чотири перевірки: той самий код не має прийматися вдруге, вікно на розсинхронізацію годинників — щонайбільше один крок, ліміт спроб має бути суворим (у шестизначного коду близько мільйона варіантів, і без ліміту це вже реальний перебір), а сама довжина коду — не менша за шість цифр. Найпідступніша з них — ліміт: його треба перевіряти з паралельних сесій, бо реалізації часто рахують спроби в межах однієї сесії й розсипаються, коли запити йдуть з кількох.
Як перевірити перелічування акаунтів?
Базова процедура — пара запитів: один з логіном, який точно існує, другий з завідомо неіснуючим, обидва з невірним паролем; далі порівнюємо відповіді за чотирма вимірами. Текст повідомлення — очевидний і найчастіше вже закритий; канонічний зразок нейтрального формулювання виглядає як Login failed; Invalid user ID or password.. Три інші виміри пропускають регулярно: статус відповіді (сторінка на око однакова, а на наявний логін приходить 200, на відсутній — 403), довжина тіла й . Часовий канал найтихіший: якщо на наявному акаунті сервер додатково шле листа чи звіряє хеш, а на відсутньому виходить одразу, різниця в сотні мілісекунд стабільно видає валідні логіни; лікується це асинхронним надсиланням або однаковим обсягом роботи в обох гілках. І важливий нюанс кваліфікації знахідки: різна відповідь буває не помилкою конфігурації, а свідомим рішенням дизайну — тоді сперечатися треба з вимогами, а не з розробником, і в тікеті це формулюється саме так.
Форма логіну — не єдиний канал перелічування. Де ще шукати?
Скрізь, де застосунок реагує на факт існування акаунта. Перший кандидат — відновлення пароля: «лист надіслано» проти «такого користувача немає» видає базу логінів швидше за форму входу. Далі йдуть повторне надсилання листа підтвердження, реєстрація («email уже зайнято»), багатокроковий вхід, де перший крок приймає лише логін, персональні URI на кшталт /u/ivan та форми з контрольними питаннями — останні взагалі не можна показувати, доки людина не підтвердила володіння поштою. Багатокроковий вхід окремо небезпечний тим, що дає атакувальникові дешеву розвідку перед credential stuffing: спершу відсіюємо неіснуючі логіни, потім бʼємо лише по реальних, і сумарний обсяг спроб падає до непомітного. Для тесту це означає, що перевірку однакової відповіді ставлять не одну на форму входу, а по одній на кожен такий канал.
Автотест на логін чекає точного значення Retry-After у відповіді 429. Що з ним не так?
Він перевіряє поведінку, якої безпековий канон вимагає не мати. На вичерпаний ліміт форма автентифікації має віддавати загальну відповідь 429 Too Many Requests без значень, точних настільки, щоб за ними планувати наступні спроби, — інакше ви самі підказуєте атакувальникові розклад. Специфікації це не суперечить: у RFC заголовок при 429 описаний як MAY, тобто сервер його взагалі не зобовʼязаний надсилати. Плутанина виникає тому, що в API-тестуванні ми звикли до протилежного — там Retry-After корисний і його справді , але то інша модель загроз. Правильний асерт для форми входу: спрацював ліміт, код 429, тіло не розкриває ні ключа ліміту, ні залишку спроб, ні того, чи існує акаунт.
Рейт-ліміт заведено на ключ «IP плюс логін». Чому це не працює?
Тому що кошик створюється на кожну пару, а не на адресу: для кожного нового логіна лічильник стартує з нуля, тож з однієї IP можна обійти скільки завгодно акаунтів і не переповнити жоден кошик. проходить крізь такий ключ як крізь відчинені двері — тобто ліміт не тримає рівно той сценарій, заради якого його й ставили. Помилка живуча, бо виглядає розумною: «рахуємо точніше, щоб не карати сусідів по NAT». Правильний підхід — кілька незалежних ключів одночасно, а не один складений: окремо на акаунт, окремо на адресу, і тоді зміна логіна не обнуляє лічильник адреси. Перевіряється це не логікою на папері, а прогоном: серія спроб з однієї адреси по різних логінах має впертися в якийсь ліміт, і якщо не впирається — знахідка.
Ми поставили CAPTCHA на форму входу. Ризик закрито?
Залежить від того, який саме , і канон дає три різні вердикти. Проти password spraying CAPTCHA пропонується як альтернатива блокуванню — вона підвищує вартість масового прогону, не даючи атакувальникові закривати чужі акаунти. Проти автоматизованих спроб входу вона працює як шар , а не як запобіжник, і блокування собою не заміняє. А коли модель загрози — відмова в обслуговуванні, користі від головоломок немає жодної: сервер усе одно приймає й обробляє потік запитів. Поруч живуть сусідні шари з прямим наслідком для нас: приховане , яке ламає автотест, коли той заповнює всі поля форми скопом, і — навмисне сповільнення відповіді, яке в звіті виглядає як і його починають «лікувати» ретраями.
Що перевіряти у флоу «Забув пароль»?
Найперше запамʼятати рамку: тут людина так само доводить, що вона — це вона, тож планка не може бути нижчою, ніж на звичайному вході — усе, що ви вимагаєте від логіну, вимагається й тут. Форма запиту: однакове повідомлення й однаковий час для наявного та відсутнього акаунта, жодних змін стану акаунта до подання валідного токена, у розрахунку на акаунт або CAPTCHA — інакше чужу поштову скриньку заллють листами з вашого ж домену. Токен: криптостійкий і достатньо довгий, привʼязаний до конкретного користувача, одноразовий; посилання не будується з заголовка Host (це Host Header Injection, і лист поїде з чужим доменом), а сторінка скидання ставить Referrer-Policy: no-referrer, щоб токен не витік у реферері до сторонніх ресурсів. Після зміни: лист-сповіщення без самого пароля всередині, без автоматичного входу — і найчастіше пропущене — інвалідація наявних сесій, бо інакше пароль новий, а сесія атакувальника жива. Останній пункт варто називати першим: саме він перетворює «інцидент закрито» на «інцидент триває».
Що робити з контрольними питаннями в легасі-продукті?
Спершу зафіксувати статус: канон каже, що прийнятних застосувань у безпечному ПЗ у них немає — за NIST це вже не прийнятний фактор, стандарт забороняє пропонувати їх під час вибору пароля, і єдиним механізмом скидання вони бути не можуть. Але легасі нікуди не подінеться, і шпаргалка OWASP свій статус позначає прямо: поради дано саме для випадку, коли викинути механізм не виходить. З них ростуть перевірки: відповіді зберігаються за паролевою гігієною (тобто хешованими, а не текстом), питання з банку не підмінюється, доки користувач не відповів правильно (інакше форма перетворюється на оракул), невірна відповідь збільшує лічильник невдалих спроб, а сама форма з питаннями показується лише після підтвердження володіння поштою — інакше вона стає ще одним каналом перелічування. І окремо: пароль плюс контрольне питання другим фактором не рахується, тож продавати цю пару як «у нас є 2FA» не можна.
Три кейси з робочого життя: як довести усіма чотирма вимірами, а не одним текстом помилки; як розібрати тікет «блокування налаштоване, перебір закрито» й показати, чого воно не ловить; і як не написати автотести на форму входу так, щоб вони перевіряли неправильну поведінку або самі ламалися об захист. Скрізь — що дивитися і чому саме це.
Кейс 1. Перелічування: одного тексту помилки замало
Тікет закрито з коментарем «повідомлення однакове для будь-якого логіна, перелічування немає». Питання, яке варто поставити першим: однакове де — на екрані чи у відповіді сервера? Порівнювати треба чотири величини, і три з них на екрані не видно.
| Вимір | Як витікає | Чим перевіряти |
|---|---|---|
| Текст повідомлення | «Користувача не знайдено» проти «Невірний пароль» | порівняння рядків відповіді |
| Код відповіді | 200 на наявному, 403 на відсутньому — сторінка на око однакова | статус HTTP, не вміст сторінки |
| Довжина тіла | зайвий блок розмітки чи інший ідентифікатор форми | Content-Length або довжина тексту |
| Час відповіді | на наявному акаунті сервер ще й шле листа або звіряє хеш | медіана по серії, не одне вимірювання |
тут — пара запитів з однаковим невірним паролем: один на логін, який точно існує, другий на завідомо відсутній.
import { test, expect, type APIRequestContext } from '@playwright/test';
const KNOWN = 'real.user@example.com'; // акаунт існує
const ABSENT = 'no.such.user.9f2a@example.com'; // акаунта немає
const WRONG_PASSWORD = 'Definitely-Not-The-Password-1';
type Probe = { status: number; length: number; body: string; ms: number };
async function probe(api: APIRequestContext, login: string): Promise<Probe> {
const started = Date.now();
const res = await api.post('/api/login', {
data: { login, password: WRONG_PASSWORD },
});
const body = await res.text();
return { status: res.status(), length: body.length, body, ms: Date.now() - started };
}
const median = (xs: number[]) => [...xs].sort((a, b) => a - b)[Math.floor(xs.length / 2)];
test('відповідь на наявний і відсутній логін не відрізняється', async ({ playwright }) => {
const api = await playwright.request.newContext({ baseURL: 'https://app.example.com' });
const known: Probe[] = [];
const absent: Probe[] = [];
for (let i = 0; i < 12; i++) {
known.push(await probe(api, KNOWN));
absent.push(await probe(api, ABSENT));
}
expect(known[0].status, 'код відповіді розрізняє акаунти').toBe(absent[0].status);
expect(known[0].body, 'текст помилки розрізняє акаунти').toBe(absent[0].body);
expect(
Math.abs(known[0].length - absent[0].length),
'довжина тіла розрізняє акаунти',
).toBeLessThan(8);
const gap = Math.abs(median(known.map((p) => p.ms)) - median(absent.map((p) => p.ms)));
expect(gap, `стабільна різниця ${gap} мс — це таймінговий канал`).toBeLessThan(100);
await api.dispose();
});
Що дивитися і чому:
- Медіана, а не одне вимірювання. Мережа шумить, і одна проба нічого не доводить у жоден бік. Серія з десятка запитів на кожен логін і порівняння медіан відсіює шум; якщо різниця тримається від прогону до прогону — це вже канал, а не збіг.
- Заведіть під це окремий акаунт і памʼятайте про лічильник. Дванадцять невдалих спроб під реальним логіном цілком можуть спрацювати як і заблокувати акаунт — далі ви вимірюватимете вже поведінку блокування, а не перелічування. Тому або тестове середовище з відомою політикою, або одноразовий акаунт, або узгоджений виняток.
- Довжина порівнюється з , а не байт у байт. У тілі майже завжди є чи ідентифікатор запиту змінної довжини. Жорсткий на рівність тут дасть фальшивий червоний; різниця в кілька байтів нормальна, різниця в десятки — привід подивитися, що саме додалося.
- Різниця не завжди дефект реалізації. Продукт міг свідомо обрати «email уже зареєстровано» заради зручності реєстрації. Тоді знахідка формулюється як питання до вимог: такий-то, рішення приймає власник продукту, — а не як баг розробника.
Кейс 2. «Блокування налаштоване — перебір закрито»
Друга типова ситуація: у релізі зʼявилося блокування після десяти невдалих спроб, ризик у трекері закривають. Перевірка справді була, але вона доводить менше, ніж здається.
| Що перевірили | Що це доводить |
|---|---|
| Десять невдалих входів під одним логіном — акаунт заблоковано | що поріг спрацьовує проти перебору одного акаунта |
| Одинадцята спроба з правильним паролем відхилена | що блокування не косметичне і діє на успішний вхід теж |
| Ті самі спроби з іншої вкладки продовжили лічильник | що лічильник наскрізний по сесіях, а не на сесію |
| Спроби по різних логінах з однієї адреси | не перевіряли — а це і є password spraying |
| Одна спроба на акаунт по списку зі злитими парами | не перевіряли — а це і є credential stuffing |
Далі корисно покласти й детектори в одну таблицю — вона й пояснює, чому «поріг є» не дорівнює «ризик закрито».
| Атака | Лічильник на акаунті | Ліміт за IP | MFA |
|---|---|---|---|
| Перебір паролів до одного акаунта | ловить | ловить, поки адреса одна | зупиняє |
| Credential stuffing | не ловить: спроб на акаунт одиниці | не ловить: проксі-мережі | зупиняє |
| Password spraying | не ловить: спроба на акаунт одна | не ловить: логіни різні | зупиняє |
Сценарії, яких у тікеті бракувало, пишуться як звичайні негативні тести:
// розпилення: один пароль по багатьох логінах з однієї адреси
test('серія спроб по різних логінах упирається в ліміт', async ({ playwright }) => {
const api = await playwright.request.newContext({ baseURL: 'https://app.example.com' });
const logins = Array.from({ length: 30 }, (_, i) => `user${i}@example.com`);
const codes: number[] = [];
for (const login of logins) {
const res = await api.post('/api/login', { data: { login, password: 'Winter2026!' } });
codes.push(res.status());
}
// якщо всі 30 відповідей однакові й жодного 429 — ключ ліміту заведено неправильно
expect(codes, 'ліміт по кількох логінах з однієї адреси не спрацював').toContain(429);
await api.dispose();
});
Що дивитися і чому:
- Число в політиці — з вимог, а не з голови. Канон дає не цифру, а три параметри: поріг, , . Джерела між собою розходяться (три-пʼять спроб в одному місці, пʼять-десять в іншому), тож тест звіряється з вимогами продукту, і якщо вимог немає — це перша знахідка, ще до прогону.
- Зустрічний ризик перевіряють окремим сценарієм. Той самий поріг, що спиняє перебір, дозволяє чужими руками закрити акаунти, знаючи лише логіни. Тому в наборі мають бути перевірки на дорогу назад: заблокований користувач проходить через , сама форма відновлення акаунт не блокує, посилання розблокування спрацьовує рівно один раз.
- Лічильник живе на акаунті. Перевірте це явно: спроби з двох різних адрес і двох сесій мають додаватися до одного лічильника. Реалізація «поріг на сесію» виглядає робочою в ручному тесті й не витримує двох вкладок.
- Невірна відповідь на — теж невдала спроба. Це окремий сценарій: якщо легасі-форма з питаннями має власний лічильник або не має його зовсім, ви отримали обхід порога в обхід форми входу.
Кейс 3. Автотести на вхід: три пастки
Останній кейс — не про продукт, а про наші ж тести. Форма входу обвішана захистами, і кожен з них по-своєму ламає автоматизацію або провокує написати неправильний асерт.
Пастка перша: заповнити всі поля скопом. Приховане існує саме для того, щоб робот його заповнив і видав себе.
// антипатерн: під роздачу потрапляє й приховане поле-пастка
for (const input of await page.locator('form input').all()) {
await input.fill('test');
}
// правильно: адресні локатори, honeypot лишається порожнім
await page.getByLabel('Email').fill(process.env.TEST_LOGIN!);
await page.getByLabel('Пароль').fill(process.env.TEST_PASSWORD!);
await page.getByRole('button', { name: 'Увійти' }).click();
Пастка друга: асерт на точний Retry-After. Форма входу за каноном віддає загальну відповідь без значень, за якими можна планувати повтори, — тож перевіряти треба факт ліміту, а не розклад.
test('вичерпаний ліміт віддає загальний 429', async ({ playwright }) => {
const api = await playwright.request.newContext({ baseURL: 'https://app.example.com' });
let last = await api.post('/api/login', { data: { login: 'a@example.com', password: 'x' } });
for (let i = 0; i < 25 && last.status() !== 429; i++) {
last = await api.post('/api/login', { data: { login: 'a@example.com', password: 'x' } });
}
expect(last.status()).toBe(429);
// тіло не має розкривати ні залишку спроб, ні того, чи існує акаунт
expect(await last.text()).not.toMatch(/attempts|remaining|not found|не знайдено/i);
await api.dispose();
});
Пастка третя: , який чомусь спрацьовує двічі. Перевірка одноразовості пишеться в три рядки, а ліміт спроб треба ганяти саме паралельно, бо послідовний прогін часто проходить там, де реалізація рахує спроби в межах однієї сесії.
import { authenticator } from 'otplib';
test('той самий OTP не приймається вдруге', async ({ playwright }) => {
const api = await playwright.request.newContext({ baseURL: 'https://app.example.com' });
const code = authenticator.generate(process.env.TOTP_SECRET!);
const first = await api.post('/api/login/otp', { data: { code } });
expect(first.status()).toBe(200);
const second = await api.post('/api/login/otp', { data: { code } });
expect(second.status(), 'код прийнято вдруге — одноразовість зламана').not.toBe(200);
await api.dispose();
});
test('ліміт спроб OTP тримається на паралельних запитах', async ({ playwright }) => {
const api = await playwright.request.newContext({ baseURL: 'https://app.example.com' });
const results = await Promise.all(
Array.from({ length: 12 }, () => api.post('/api/login/otp', { data: { code: '000000' } })),
);
const codes = results.map((r) => r.status());
expect(codes.some((c) => c === 429 || c === 423), 'усі 12 паралельних спроб пройшли перевірку').toBeTruthy();
await api.dispose();
});
Що дивитися і чому:
- виглядає як . Якщо після кількох невдач сервер починає навмисне тягнути час, тест почне падати по нерівномірно. Лікувати це ретраями й довшими очікуваннями — означає замаскувати працюючий захист; правильна реакція — прибрати з тесту зайві невдалі спроби або узгодити виняток для тестового середовища.
- Не всі перевірки безпеки варто автоматизувати в основній . Прогін на 25 невдалих входів у кожному псує метрики продукту й тригерить алерти безпеки. Такі сценарії тримають окремим тегом і ганяють за розкладом.
- Секрети — з оточення, дані — одноразові. Логін і пароль з
process.env, -секрет теж; акаунт під негативні сценарії краще створювати на прогін, бо заблокований загальний акаунт покладе всю сюїту. - Асерт формулюють від вимог, а не від поточної відповіді. Записали
expect(...).toBe(401)тому, що «зараз так приходить», — і зафіксували випадкову поведінку. Спершу контракт: який код і яке тіло продукт має віддавати на невдалий вхід, вичерпаний ліміт і заблокований акаунт.
Збої автентифікації і три атаки
- Можу переказати означення категорії з :2025 (систему змусили визнати невалідного користувача легітимним), назвати ознаки — неспинений перебір, дефолтні паролі, слабке відновлення, відсутня чи неефективна MFA — і : єдиним доказом лишається пароль, а правила «міняй за розкладом і ускладнюй» дають зворотний ефект.
- Розвожу , і за тим, що множиться (багато паролів на один акаунт; готові пари з чужого витоку на багато сайтів; один слабкий пароль на багато акаунтів), і розумію, чому лічильник на акаунті не бачить ані credential stuffing, ані password spraying.
- Знаю ширше означення перебору з канону — надіслати наперед визначені значення й аналізувати відповідь — і памʼятаю, звідки береться : із тіла відповіді, бо збіг статусів ще нічого не гарантує.
- Можу пояснити, чому фільтрація за IP не буває головним захистом (-мережі розмазують обсяг), чому першим засобом канон називає MFA з оцінкою Microsoft про 99,9 % зупинених компрометацій і яка типова вдалого password spraying — однаковий стартовий пароль, який мають змінити на першому вході.
Пароль: вимоги
- Тримаю в голові числа з модальностями NIST SP 800-63B-4: нижня межа
SHALL— 15 символів, коли пароль працює сам; вісім дозволені тільки в парі з другим фактором; приймати 64 символи верифікаторSHOULDуміти. - Знаю, що композиційні правила стандарт забороняє (
SHALL NOT), єдина підстава відхилити пароль — блоклист із порівнянням цілого пароля, а задовгий пароль має дати чесну помилку, а не тихо вкоротитися. - Не плутаю дві половини вимоги про зміну (планова заборонена, вимушена за свідчень компрометації обовʼязкова), памʼятаю розходження з -ATHN-07 через режими відповідності на кшталт PCI DSS і класичний обхід історії — кілька змін поспіль із поверненням до початкового пароля.
Пароль: зберігання очима QA
- Можу пояснити, чому продукт, який віддає вам раніше збережений секрет (на екрані чи листом), тримає його в оборотному вигляді, і чому кнопка «показати» над полем вводу до цієї знахідки не належить — таку зручність канон навпаки схвалює.
- Знаю, чому швидкі хеші на кшталт
SHA-256не годяться (усе впирається в стійкість до офлайн-перебору), де читається , звідки береться межа 72 байти в bcrypt — і дві суміжні вимоги, які видно з інтерфейсу: підтвердження поточного пароля при зміні й звірка нового зі злитими наборами.
Другий фактор і одноразові коди
- Можу пояснити, що MFA — про тип доказу, а не про кількість полів (ні пароль плюс PIN, ні пароль плюс нею не є), і назвати типовий злам незалежності факторів — -застосунок на тому самому пристрої, з якого йде вхід.
- Орієнтуюся в ранжуванні факторів ( на базі FIDO2 стійкий до фішингу, U2F надійний тим, що приватний ключ не покидає токен, коди телефонною мережею NIST позначає як ) і памʼятаю найтонше місце — заміну фактора можна робити лише після повторного підтвердження особи тим, що вже налаштоване.
- Розвожу і TOTP (у першому лічильник рахує події, у другому його місце займає час, поділений на кроки по 30 секунд за рекомендацією RFC 6238) і називаю чотири перевірки коду: одноразовість, вікно щонайбільше в один крок, суворий ліміт спроб з паралельних сесій, довжина не менша за шість цифр.
Перелічування акаунтів
- Знаю мету тест-айтема WSTG-IDNT-04, всі чотири виміри однакової відповіді (текст, код, довжина тіла, час), канонічний зразок нейтрального повідомлення
Login failed; Invalid user ID or password.— і те, що різниця у відповідях буває рішенням дизайну, а не дефектом реалізації. - Перевіряю не лише форму входу: , повторне надсилання підтвердження, реєстрацію, багатокроковий вхід, персональні URI та форму з контрольними питаннями (її показують тільки після підтвердження володіння поштою) — і розумію природу таймінгового каналу, який лікується асинхронним надсиланням листа або однаковим обсягом роботи в обох гілках.
Блокування, рейт-ліміт, CAPTCHA
- Називаю три параметри політики блокування (поріг, , тривалість — можливо, експоненційну), не ловлюся на питання «скільки спроб» і знаю механіку лічильника: він на акаунті, наскрізний по сесіях і зростає також тоді, коли на контрольне питання відповіли неправильно.
- Памʼятаю зустрічний блокування — в обслуговуванні чужими руками — і три елементи розвʼязання: вхід через відновлення пароля, заборона блокувати акаунт самою формою відновлення, одноразове посилання розблокування.
- Можу пояснити дефект кошика на пару «IP плюс логін» (для кожного нового логіна лічильник стартує з нуля, тож з однієї адреси обходять скільки завгодно акаунтів), знаю, що ключів має бути кілька, і що на вичерпаний ліміт форма віддає загальний
429, з якого не можна вирахувати розклад наступної хвилі спроб. - Тримаю три вердикти щодо окремо (альтернатива блокуванню проти password spraying, без заміни блокування проти автоматизованих входів, нуль користі проти відмови в обслуговуванні) і памʼятаю два сусідні шари з прямим наслідком для автотестів: ламає сценарій, а виглядає як .
Відновлення пароля
- Тримаю рамку (людина тут так само доводить, що вона — це вона, тож планка не нижча за звичайний вхід), перевіряю форму запиту за трьома пунктами — однакове повідомлення й однаковий час, жодних змін стану до подання валідного токена, на акаунт або CAPTCHA — і знаю вимоги до токена: непередбачуваний, одноразовий, дійсний для одного користувача, адреса в листі не збирається з заголовка
Host, а сторінка скидання ставитьReferrer-Policy: no-referrer. - Памʼятаю три дії після зміни (лист-сповіщення без самого пароля, жодного автоматичного входу, інвалідація наявних сесій), статус контрольних питань (не прийнятний фактор за NIST, поради OWASP — лише для легасі: відповіді зберігати як паролі, питання не міняти, доки користувач не відповів правильно) і те, що повернення доступу до втраченого другого фактора не повинно ставати чорним ходом повз MFA.
Квіз
Перед стартом
- Питань: 17
- Поріг «зараховано»: ≥70% правильних відповідей.
- Результат впливає на прогрес; завалені питання підуть у чергу повторення.
- Квіз впливає на компліт теми: тема стає «пройдено», лише коли прочитано теорію І квіз складено на ≥70%.
Питання
Як OWASP Top 10:2025 означує збої автентифікації?