Реалізація обмеження спроб входу (Brute-Force Protection) на сайті

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

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

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація обмеження спроб входу (Brute-Force Protection) на сайті
Середня
~1 робочий день
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Впровадження обмеження спроб входу (захист від перебору паролів) на сайті

Атаки перебору паролів - один з найпоширеніших векторів компрометації облікових записів. Без обмежень зловмисники можуть перевіряти тисячі паролів за хвилину за допомогою автоматизованих скриптів.

Стратегії захисту

Захист від перебору паролів будується з кількох рівнів:

  1. Rate limiting — обмеження кількості спроб за період
  2. Account lockout — тимчасове блокування облікового запису
  3. IP блокування — блокування джерела атаки
  4. Progressive delays — зростаючі затримки між спробами
  5. CAPTCHA — після N невдалих спроб

Реалізація на Laravel

// app/Http/Controllers/Auth/LoginController.php
class LoginController extends Controller
{
    protected int $maxAttempts = 5;
    protected int $decayMinutes = 15;

    public function login(Request $request)
    {
        // Вбудований throttle Laravel використовує кеш (Redis/database)
        if ($this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);
            return $this->sendLockoutResponse($request);
        }

        if (Auth::attempt($request->only('email', 'password'))) {
            $this->clearLoginAttempts($request);
            return redirect()->intended('/dashboard');
        }

        $this->incrementLoginAttempts($request);
        return back()->withErrors(['email' => 'Невірні облікові дані']);
    }
}

Трейт ThrottlesLogins використовує ключ виду email|IP — блокує конкретну комбінацію, не весь IP.

Користувацька реалізація через Redis

class BruteForceProtection
{
    private Redis $redis;
    private int $maxAttempts = 5;
    private int $lockoutSeconds = 900; // 15 хвилин
    private int $windowSeconds = 300;  // 5 хвилин

    public function attempt(string $key): bool
    {
        $redisKey = "login_attempts:{$key}";
        $count = $this->redis->incr($redisKey);

        if ($count === 1) {
            $this->redis->expire($redisKey, $this->windowSeconds);
        }

        if ($count > $this->maxAttempts) {
            $this->redis->setex("lockout:{$key}", $this->lockoutSeconds, 1);
            return false;
        }

        return true;
    }

    public function isLocked(string $key): bool
    {
        return (bool) $this->redis->exists("lockout:{$key}");
    }

    public function getLockoutTtl(string $key): int
    {
        return $this->redis->ttl("lockout:{$key}");
    }

    public function reset(string $key): void
    {
        $this->redis->del("login_attempts:{$key}", "lockout:{$key}");
    }
}

Progressive Delay (зростаючі затримки)

Замість повної блокування — збільшення затримки з кожною невдалою спробою:

// Затримки: 1с → 2с → 4с → 8с → 16с → 32с (максимум)
$delay = min(pow(2, $attempts - 1), 32);
sleep($delay);

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

Диференціація блокувань

Важливо розділяти рівні блокування:

Рівень Ключ Умова Тривалість
За email login:email:[email protected] 5 спроб за 5 хв 15 хв
За IP login:ip:1.2.3.4 20 спроб за 5 хв 30 хв
Глобальна login:global 1000 спроб за 1 хв Алерт

Блокування лише за IP може зашкодити користувачам за NAT/проксі. Блокування лише за email легко обійти з іншого IP.

CAPTCHA після кількох невдалих спроб

// У контролері
$attempts = $this->limiter->attempts($throttleKey);
$showCaptcha = $attempts >= 3;

return view('auth.login', compact('showCaptcha'));
@if ($showCaptcha)
    <div class="cf-turnstile" data-sitekey="{{ config('services.turnstile.site_key') }}"></div>
@endif

Сповіщення користувача

При успішному вході після кількох невдалих спроб — поштове сповіщення:

// Після успішної аутентифікації
if ($previousFailedAttempts > 2) {
    Mail::to($user)->queue(new SuspiciousLoginNotification($request->ip()));
}

Моніторинг

Логування всіх невдалих спроб у структурованому форматі:

Log::warning('Failed login attempt', [
    'email'      => $request->email,
    'ip'         => $request->ip(),
    'user_agent' => $request->userAgent(),
    'timestamp'  => now()->toIso8601String(),
]);

Алерт у Grafana/Datadog при піку подій невдалого входу — ознака активної атаки.

Тривалість реалізації

  • Базовий throttle Laravel: 1 день
  • Користувацька реалізація Redis з прогресивними затримками: 2–3 дні
  • Інтеграція з моніторингом та сповіщеннями: +1 день