Skip to content

Rate Limiting and Captcha Protection

The authentication system includes rate limiting and captcha protection to prevent brute force attacks and automated login attempts.

Global Rate Limiting

The system uses a global rate limiter to track all failed login attempts across the entire application, regardless of the user or IP address. This helps protect against distributed brute force attacks where attackers might try different usernames from different IPs.

Configuration

  • Key: global_failed_logins
  • Decay Time: 300 seconds (5 minutes)
  • Captcha Threshold: 10 attempts

How it Works

  1. Every failed login attempt (wrong password or non-existent user) increments the global counter
  2. The counter decays after 5 minutes
  3. When the number of recent failed attempts exceeds the threshold:
    • The login form displays a captcha
    • All login attempts require a valid captcha solution
  4. The captcha requirement remains until the number of failed attempts drops below the threshold

Implementation Details

The rate limiting is implemented in the AuthController using Laravel's RateLimiter component:

php
// Check failed attempts count
$recentFailedAttempts = $limiter->attempts(self::GLOBAL_LOGIN_ATTEMPTS_KEY);

// Determine if captcha is needed
$displayCaptcha = $recentFailedAttempts >= self::CAPTCHA_THRESHOLD;

// Increment counter on failed attempts
$limiter->hit(self::GLOBAL_LOGIN_ATTEMPTS_KEY, self::DECAY_SECONDS);

Validation

When the captcha is required:

  • The login form includes Cloudflare Turnstile captcha
  • The cf-turnstile-response field becomes required
  • Failed captcha validation prevents login even with correct credentials

This provides an additional layer of security against automated attacks while maintaining a good user experience during normal operation.