Learn how to prevent rate limiting attacks with real code examples and best practices. Protect your application from brute force attacks and denial of service.
What is Missing Rate Limiting and How Does it Work?
Missing Rate Limiting is a security vulnerability that occurs when an application fails to limit the number of requests a user or IP address can make within a specific time period. Without proper rate limiting, attackers can perform:
Brute force attacks on authentication endpoints
Denial of Service (DoS) attacks
API abuse and scraping
Resource exhaustion
Excessive costs in pay-per-use services
This guide covers Rate Limiting implementation, examples, prevention methods, and how to properly secure your endpoints using real-world techniques.
One Simple Rate Limiting Attack Example
Consider this vulnerable API endpoint without rate limiting:
An attacker could make thousands of requests per second to this endpoint:
while true; do curl -X POST http://api.example.com/login; done
This could lead to:
Server overloadIncreased costsSuccessful brute force attacks
Rate Limiting Prevention Methods: How to Fix Your Code
The most efficient way to fix Missing Rate Limiting is by implementing a rate limiter middleware that tracks and limits requests based on various identifiers (IP address, user ID, API key).
Rate limiting can be implemented using different strategies such as fixed window, sliding window, or token bucket algorithms. Most frameworks and cloud services provide built-in rate limiting solutions.
const express = require('express');
const rateLimit = require('express-rate-limit');
const router = express.Router();
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
router.get('/', limiter, function (req, res) {
setHeaders(res);
let params = getSessionParams(req);
res.render('pages/index', params);
});
Fix Explanation
The vulnerable code has no request limiting mechanism.The fix uses express-rate-limit middleware.Configures a 15-minute window with max 100 requests per IP.Additional options available for customization (error messages, headers, etc.).
from flask import Flask
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
limiter = Limiter(
app,
key_func=get_remote_address,
default_limits=["200 per day", "50 per hour"]
)
@app.route("/api/data")
@limiter.limit("1 per second")
def get_data():
return jsonify({"data": "sensitive information"})
Fix Explanation
The vulnerable code allows unlimited requests to the endpoint.The fix uses Flask-Limiter to implement rate limiting.Defines both global and route-specific limits.Supports multiple time windows and limit types.
Vulnerable Code
@RestController
public class ApiController {
@GetMapping("/api/resource")
public ResponseEntity<?> getResource() {
return ResponseEntity.ok(resourceService.getData());
}
}
Fixed Code
@RestController
public class ApiController {
@GetMapping("/api/resource")
@RateLimiter(name = "basic")
public ResponseEntity<?> getResource() {
return ResponseEntity.ok(resourceService.getData());
}
}
@Configuration
public class RateLimitConfig {
@Bean
public RateLimiterConfig rateLimiterConfig() {
return RateLimiterConfig.custom()
.limitForPeriod(10)
.limitRefreshPeriod(Duration.ofSeconds(1))
.timeoutDuration(Duration.ofMillis(500))
.build();
}
}
Fix Explanation
The vulnerable code has no request throttling.The fix uses Spring Cloud Circuit Breaker's RateLimiter.Configures limits per time period and timeout duration.Provides fallback mechanisms for rate limit exceeded scenarios.
Vulnerable Code
Route::post('/api/endpoint', function (Request $request) {
return response()->json(['status' => 'success']);
});
Fixed Code
Route::middleware('throttle:60,1')->group(function () {
Route::post('/api/endpoint', function (Request $request) {
return response()->json(['status' => 'success']);
});
});
// In RouteServiceProvider.php
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
}
Fix Explanation
The vulnerable code allows unlimited API requests.The fix uses Laravel's built-in throttle middleware.Limits requests to 60 per minute per user/IP.Supports custom rate limiting rules and response handling.
import "golang.org/x/time/rate"
var limiter = rate.NewLimiter(rate.Every(time.Second), 10)
func rateLimitMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.Error(w, "Too many requests", http.StatusTooManyRequests)
return
}
next.ServeHTTP(w, r)
})
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
router := mux.NewRouter()
router.Handle("/", rateLimitMiddleware(http.HandlerFunc(handler)))
Fix Explanation
The vulnerable code has no request rate control.The fix uses Go's rate package to implement token bucket algorithm.Limits to 10 requests per second.Returns 429 Too Many Requests when limit is exceeded.
Need more help in implementing Rate Limiting?
Mobb supports fixing many forms of Missing Rate Limiting vulnerabilities, and can mitigate your issues in batch.