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

Як системно тестувати авторизацію, щоб нові ендпойнти не відкривали чужих даних?

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

1. Матриця доступу. Для кожного ресурсу - таблиця «роль × дія → очікуваний результат»:

гість власник інший користувач модератор адмін іншої організації
переглянути 404 200 404 200 404
змінити 401 200 403 403 404
видалити 401 200 403 200 404

Матриця - і документація, і основа тестів.

2. Датасети в Pest - один тест на всю матрицю:

dataset('post access', [
    'guest' => [fn () => null, 'update', 401],
    'owner' => [fn () => Post::first()->author, 'update', 200],
    'stranger' => [fn () => User::factory()->create(), 'update', 403],
]);

it('enforces access to posts', function (Closure $actor, string $action, int $status) {
    $post = Post::factory()->create();
    $user = $actor();

    $response = ($user ? $this->actingAs($user) : $this)
        ->putJson("/api/posts/{$post->id}", ['title' => 'Новий заголовок']);

    $response->assertStatus($status);

    if ($status !== 200) {
        expect($post->fresh()->title)->not->toBe('Новий заголовок');   // стан не змінився
    }
})->with('post access');

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

3. Тест «кожен маршрут захищено». Пройтися по Route::getRoutes() і переконатися, що кожен маршрут має middleware auth чи явно позначений як публічний. Новий маршрут без авторизації ламає тест одразу:

it('protects every route', function () {
    $public = ['login', 'register', 'password.request', 'home'];

    collect(Route::getRoutes())
        ->reject(fn ($route) => in_array($route->getName(), $public, true))
        ->each(fn ($route) => expect($route->gatherMiddleware())->toContain('auth'));
});

4. Тести політик напряму - швидкі модульні тести для складних правил ($user->can('update', $post)), окремо від HTTP.

5. Багатоорендність: для кожної моделі - тест «орендар A не бачить даних орендаря B» на всіх шляхах: список, деталі, пошук, експорт, фільтри.

6. Ручне й автоматизоване тестування на продакшен-подібному середовищі: два облікові записи в браузері (чи розширення на кшталт Autorize для Burp), що повторюють запити одного користувача від імені іншого.

Процес: новий ендпойнт без тестів на заборону не проходить рев'ю коду - це найдешевший спосіб не допустити IDOR.

Докладніше в документації: OWASP Web Security Testing Guide

Схожі питання