API Rate Limiting
EasyChecks if API endpoints implement proper rate limiting.
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
- Make requests up to the limit - should succeed
- Exceed the limit - should get 429 error
- Check response headers for rate limit info
- Wait for reset period - should work again
- 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
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