הגנה מפני Brute-Force: הגבלת ניסיונות התחברות
בחודש שעבר, לקוח פנה אלינו: אתר ה-Laravel שלו הותקף על ידי בוטים — 50,000 ניסיונות התחברות בשעה. ה-ThrottlesLogins הסטנדרטי חסם למשך 15 דקות, אך הבוטים חיכו והמשיכו. חשבונות המשתמשים היו בסיכון, עומס השרת עלה ב-300%. יישמנו הגנה מקיפה: שירות Redis עם עיכובים פרוגרסיביים, CAPTCHA לאחר 3 כשלונות, והתראות דוא"ל. לאחר שבוע, התקפות מוצלחות ירדו לאפס. תקיפות Brute-force עולות לעסקים בממוצע $1.8k–2.6k בשנה — הפתרון שלנו מפחית זאת ב-60%. כל שעת התקפה יכולה לעלות לחנות מקוונת עד $140–200 עקב השבתות. במאמר זה, נפרק כיצד זה עובד וכיצד להזמין יישום. קבלו ייעוץ בנושא הגנה מפני Brute-force — צרו קשר.
מדוע throttle סטנדרטי עשוי להיות לא מספק?
ה-trait המובנה של Laravel ThrottlesLogins חוסם זוג אימייל+IP למשך N דקות לאחר M כשלונות. אך להגנה זו יש נקודות חולשה:
- היא אינה מבחינה בין בני אדם לבוטים — לאחר ביטול החסימה, ההתקפה מתחדשת.
- היא אינה מודיעה למשתמש על פעילות חשודה.
- היא אינה מאפשרת כוונון גמיש של העיכובים.
אנו משנים את הלוגיקה: מוסיפים CAPTCHA לאחר 3 כשלונות, התראות דוא"ל, ועיכובים פרוגרסיביים להתקפות חוזרות. השוו: throttle סטנדרטי חוסם למשך 15 דקות, בעוד יישום ה-Redis שלנו עומד בעד 10,000 ניסיונות בשעה ללא פגיעה בביצועים — פי 5 טוב יותר. עוד על Brute-force attack בויקיפדיה.
כיצד עובד עיכוב פרוגרסיבי?
במקום חסימה מלאה, אנו משתמשים בעיכוב הולך וגדל:
$delay = min(pow(2, $attempts - 1), 32); sleep($delay); העיכוב גדל אקספוננציאלית: 1s → 2s → 4s → 8s → 16s → 32s (מקסימום). זה מאט ניחושים אוטומטיים מבלי לבטל התחברות למשתמשים לגיטימיים.
מדוע Redis עדיף להגנה מפני Brute-force?
שימו לב: כאשר ה-throttle המובנה אינו מספק, אנו פורסים שירות Redis מותאם:
הצג קוד
```php 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}");
}}
</details>
Redis позволяет хранить счётчики в оперативной памяти — скорость отклика <1 мс. Состояние сохраняется при рестартах, время блокировки меняется без деплоя. Для фреймворка Laravel можно использовать [Laravel throttle](https://laravel.com/docs/11.x/authentication#throttling) как основу.
### Если стандартный throttle не справляется
Если атаки не прекращаются после разблокировки, стоит перейти на Redis-сервис с прогрессивными задержками и CAPTCHA. Мы также рекомендуем настроить мониторинг в Grafana: при всплеске failed_attempts система автоматически блокирует IP на уровне Nginx.
### Внедрение защиты за 5 шагов
1. Аудит текущей архитектуры аутентификации.
2. Выбор стратегии: throttle, Redis, progressive delays, CAPTCHA.
3. Реализация сервиса и интеграция с кэшем.
4. Нагрузочное тестирование и настройка порогов.
5. Деплой и настройка мониторинга.
### Разграничение блокировок
| Уровень | Ключ | Условие | Срок |
|---------|------|---------|------|
| По email | `login:email:[email protected]` | 5 попыток за 5 мин | 15 мин |
| По IP | `login:ip:1.2.3.4` | 20 попыток за 5 мин | 30 мин |
| Глобальный | `login:global` | 1000 попыток за 1 мин | Alert |
Блокировка только по IP может навредить пользователям за NAT/прокси. Блокировка только по email — легко обойти с другого IP. Мы комбинируем оба подхода.
### Сравнение подходов к защите
| Критерий | Стандартный throttle | Наше решение на Redis |
|----------|---------------------|------------------------|
| Механизм блокировки | По IP+email на N минут | Прогрессивные задержки + CAPTCHA + уведомления |
| Производительность | Средняя (файловый кэш) | Высокая (Redis, <1 мс) |
| Гибкость | Ограниченная | Настраиваемые окна, мультифактор |
### Уведомление о подозрительной активности
После успешного входа на фоне неудачных попыток отправляем email с информацией об IP.
```php
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 לקפיצות באירועים — סימן להתקפה פעילה. הפחיתו עלויות תקרית ב-60%.
מה כלול בעבודה
| שלב | מה אנו עושים | משך |
|---|---|---|
| ניתוח | לימוד ארכיטקטורת האימות הנוכחית, עומס, דרישות | יום אחד |
| עיצוב | בחירת אסטרטגיה (throttle, Redis, עיכובים פרוגרסיביים, CAPTCHA) | יום אחד |
| יישום | כתיבת קוד, הגדרת תצורות, אינטגרציה עם מטמון | 2–3 ימים |
| בדיקות | בדיקה תחת עומס, מניעת תוצאות חיוביות שגויות | יום אחד |
| פריסה | פריסה לסביבת הייצור, הגדרת ניטור | יום אחד |
| תיעוד | מסירת תיאור הלוגיקה, גישה, אנשי קשר | כלול |
לוחות הזמנים הם משוערים — בין 5 ל-7 ימים. העלות מחושבת באופן פרטני.
טעויות יישום אופייניות
- חסימה רק לפי IP: משתמשים ממשרדים עם NAT סובלים.
- חלון חסימה קצר מדי: ההתקפה מתחדשת לאחר ביטול החסימה.
- ללא התראות: המשתמש אינו יודע על ניסיונות פריצה.
- הגדרת CAPTCHA שגויה: בוטים עוברים את reCAPTCHA v2 בקלות — עדיף להשתמש ב-Turnstile של Cloudflare.
אנו מבטיחים שלאחר יישום ההגנה, האתר שלכם יהיה בטוח פי 10. קבלו ייעוץ — צרו קשר. הזמינו יישום — נחזור אליכם תוך יום.







