API Rate Limiting

Easy

Checks if API endpoints implement proper rate limiting.

Estimated fix time: 15 minutes

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);
});
  • Brute Force Protection
  • JWT Token Security
  • CORS Misconfiguration

Automatically detect this issue

StackShield can automatically scan your Laravel application for this security issue and alert you when it's detected.

Start Free Trial
Was this guide helpful?