How to Fix API Rate Limiting in Laravel

Checks if API endpoints implement proper rate limiting.

authentication authorization Easy fix 15 minutes

What This Check Detects

Checks if API endpoints implement proper rate limiting.

Full Documentation

What is API Rate Limiting?

Rate limiting restricts the number of requests a user can make to your API within a time period. This prevents abuse, protects resources, and ensures fair usage.

Security Impact

Severity: Medium

  • API abuse and resource exhaustion
  • DDoS attacks
  • Brute force attacks
  • Data scraping
  • Service degradation

How to Fix

1. Apply Built-in Throttle Middleware

// routes/api.php
Route::middleware('throttle:60,1')->group(function () {
    Route::get('/user', function () {
        return auth()->user();
    });
});

2. Configure Rate Limiters

// app/Providers/RouteServiceProvider.php
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;

protected function configureRateLimiting()
{
    // Default API limiter
    RateLimiter::for('api', function (Request $request) {
        return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
    });
    
    // Authenticated users - higher limit
    RateLimiter::for('authenticated', function (Request $request) {
        return $request->user()
            ? Limit::perMinute(100)->by($request->user()->id)
            : Limit::perMinute(10)->by($request->ip());
    });
    
    // Premium users - even higher limit
    RateLimiter::for('premium', function (Request $request) {
        if ($request->user()?->isPremium()) {
            return Limit::none();
        }
        return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
    });
}

3. Apply to Routes

Route::middleware(['auth:sanctum', 'throttle:authenticated'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
});

Route::middleware(['auth:sanctum', 'throttle:premium'])->group(function () {
    Route::get('/premium/data', [PremiumController::class, 'data']);
});

4. Custom Response

// app/Http/Middleware/CustomThrottleMiddleware.php
use Illuminate\Routing\Middleware\ThrottleRequests;

class CustomThrottleMiddleware extends ThrottleRequests
{
    protected function buildException($key, $maxAttempts)
    {
        $retryAfter = $this->limiter->availableIn($key);
        
        return response()->json([
            'message' => 'Too many requests',
            'retry_after' => $retryAfter,
        ], 429);
    }
}

5. Different Limits for Different Endpoints

// Strict limits for sensitive operations
Route::post('/login', [AuthController::class, 'login'])
    ->middleware('throttle:5,1'); // 5 per minute

// Generous limits for reading
Route::get('/posts', [PostController::class, 'index'])
    ->middleware('throttle:100,1'); // 100 per minute

Verification Steps

  1. Make requests up to the limit - should succeed
  2. Exceed the limit - should get 429 error
  3. Check response headers for rate limit info
  4. Wait for reset period - should work again
  5. Verify different limits for different user types

Response Headers

Laravel includes helpful headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Retry-After: 60

Advanced Configuration

Multiple Limits

RateLimiter::for('api', function (Request $request) {
    return [
        Limit::perMinute(60),
        Limit::perDay(1000),
    ];
});

Dynamic Limits

RateLimiter::for('api', function (Request $request) {
    $limit = $request->user()->rate_limit ?? 60;
    return Limit::perMinute($limit)->by($request->user()->id);
});

Related Issues

  • Brute Force Protection
  • JWT Token Security
  • CORS Misconfiguration

Related Security Checks

Check Your Laravel App for This Vulnerability

StackShield runs this check and 30+ others automatically. No code installation required.

Start Free Trial