QA Interview Hub · База знань · Тести

API

Безпека API

OWASP API Top 10: доступ і автентифікація

OWASP API Security Top 10 — список найпоширеніших ризиків API. QA не обов'язково бути пентестером, але базові перевірки з нього має робити кожен.

BOLA (Broken Object Level Authorization), вона ж IDOR — перше місце в списку. Користувач змінює id в URL чи тілі й отримує чужий об'єкт: GET /accounts/43 з токеном власника рахунку 42. Перевірка: два тестові користувачі, ресурс першого запитується токеном другого, чекаємо 403 або 404. Перевіряю всі методи, не лише GET: чужий рахунок можна й змінити, і видалити.

Broken Function Level Authorization — звичайний користувач викликає адмінську функцію, наприклад DELETE /admin/users/5, бо фронтенд просто ховає кнопку, а сервер роль не перевіряє.

Broken Authentication — слабкі місця логіну і токенів:

  • Немає ліміту спроб логіну, і пароль можна підібрати.
  • Токен не інвалідується після logout чи зміни пароля.
  • Токен передається в URL і осідає в логах.
  • Зміна пароля чи email без повторного підтвердження.
На співбесіді: Найважливіше в безпеці API — BOLA або IDOR: я перевіряю доступ до чужого ресурсу з токеном іншого користувача для всіх методів. Також перевіряю адмінські функції під звичайною роллю і роботу з токенами: logout, ліміт спроб логіну, інвалідацію після зміни пароля.

Зайві дані, mass assignment, ін'єкції, rate limiting

Excessive data exposure — API віддає більше, ніж показує UI, сподіваючись, що фронтенд відфільтрує. У відповіді профілю можуть бути хеш пароля, внутрішні прапорці, повний номер картки. Перевіряю сирий JSON, а не екран, і використовую схему з additionalProperties: false.

Mass assignment — сервер біндить усе тіло запиту на модель. Користувач додає в PATCH /users/me поле "role": "admin" або "balance": 1000000, і воно зберігається. Тест: відправити поля, які клієнт не має права змінювати, і перевірити через GET, що вони не змінились.

{ "name": "Ivan", "role": "admin", "isVerified": true }

Injection — SQL, NoSQL чи command injection через параметри. Базово перевіряю лапки, ' OR 1=1--, спецсимволи і дуже довгі рядки в полях і query: відповідь має бути 4xx або коректний результат, без 500 і без SQL-помилки в тілі.

Rate limiting (у сучасному списку — unrestricted resource consumption) — без лімітів API можна заддосити або перебрати коди з SMS. Перевіряю, що після ліміту приходить 429 з Retry-After, а ліміт діє на користувача чи IP, а не лише на один ендпоінт. Окремо — розмір сторінки й файлів: limit=100000 не має покласти сервіс.

На співбесіді: Я дивлюся сирий JSON на зайві чутливі поля, пробую mass assignment, додаючи в тіло role чи balance, і базові ін'єкції в рядкових полях. Також перевіряю rate limiting: після ліміту має бути 429, а не нескінченні спроби.

Пастки JWT

Будову JWT і базові тести токенів я вже знаю; тут — типові вразливості, про які питають на senior-рівні.

  • Алгоритм none. Атакувальник ставить у header "alg": "none" і прибирає підпис. Сервер, який довіряє полю alg, прийме такий токен. Очікування: 401.
  • Підміна алгоритму RS256 на HS256. Сервер з асиметричним ключем приймає токен, підписаний симетрично його ж публічним ключем. Правильна реалізація жорстко фіксує очікуваний алгоритм.
  • Слабкий секрет HS256. Короткий секрет підбирається офлайн, і тоді можна підписати будь-який payload.
  • Чутливі дані в payload. Payload лише закодований, тому email, телефон чи номер рахунку там видно кожному.
  • Відсутність перевірки exp, aud, iss. Токен іншого сервісу чи середовища не повинен прийматися.
  • Неможливість відкликати токен. JWT stateless, тому після logout чи блокування користувача access token живе до exp. Захист — короткий час життя access token, ротація refresh token і denylist для критичних випадків.

Для тестів я декодую токен (payload читається без ключа), змінюю роль чи sub і відправляю без перепідпису, а також перевіряю токен зі stage на dev.

На співбесіді: Крім простроченого й зіпсованого токена, я перевіряю alg: none, токен іншого середовища і чутливі дані в payload. Також питаю, як команда відкликає токени, бо JWT stateless і після logout живе до exp.