---
title: Implement Brute-force Protection
impact: MEDIUM
impactDescription: prevents password guessing and credential stuffing attacks
tags: brute-force, rate-limiting, authentication, security, php
---

## Implement Brute-force Protection

Without brute-force protection, attackers can use automated scripts to try millions of password combinations against your login endpoints. You must implement rate limiting or progressive delays for sensitive actions like authentication, password resets, and MFA verification.

**Incorrect (no protection):**

```php
// Standard login without limits
public function login(Request $request) {
    if (Auth::attempt($request->only('email', 'password'))) {
        return redirect()->intended('dashboard');
    }
    return back()->withErrors(['email' => 'Invalid credentials']);
}
```

**Correct (rate limiting and locking):**

```php
// 1. Using Laravel's built-in Rate Limiter (Recommended)
use Illuminate\Support\Facades\RateLimiter;

public function login(Request $request) {
    $throttleKey = Str::lower($request->input('email')) . '|' . $request->ip();

    if (RateLimiter::tooManyAttempts($throttleKey, 5)) {
        $seconds = RateLimiter::availableIn($throttleKey);
        return back()->withErrors([
            'email' => "Too many attempts. Retry in {$seconds} seconds."
        ]);
    }

    if (Auth::attempt($request->only('email', 'password'))) {
        RateLimiter::clear($throttleKey);
        return redirect()->intended('dashboard');
    }

    RateLimiter::hit($throttleKey, 60); // 1 minute window
    return back()->withErrors(['email' => 'Invalid credentials']);
}

// 2. Progressive Delay (Plain PHP)
if ($loginFailed) {
    $attempts = $_SESSION['login_attempts'] ?? 0;
    $_SESSION['login_attempts'] = $attempts + 1;
    
    // Slow down attackers
    if ($attempts > 3) {
        sleep(pow(2, $attempts - 3)); // Exponential backoff
    }
}
```

**Best Practices:**
1. **IP + Account Limiting**: Track attempts by both IP address and the targeted account (email/username).
2. **CAPTCHA**: Trigger a CAPTCHA (e.g., reCAPTCHA v3) after a certain number of failed attempts.
3. **Lockout Policy**: Temporarily disable an account after X failed attempts (e.g., lock for 30 minutes after 10 failures).
4. **Monitoring**: Log multiple failures from a single IP to trigger WAF (Web Application Firewall) blocks.

**Tools:** Laravel RateLimiter, Symfony Rate Limiter component, AWS WAF, Cloudflare Rate Limiting
