# Missing Rate Limiting

#### Tools recognizing this:

<kbd>Opengrep</kbd> <kbd>Fortify</kbd> <kbd>Checkmarx</kbd> <kbd>SonarQube</kbd> <kbd>Snyk</kbd> <kbd>Semgrep</kbd> <kbd>CodeQL</kbd>

## 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:

{% code overflow="wrap" %}

```
app.post('/login', function(req, res) {
    const { username, password } = req.body;
    authenticateUser(username, password);
});
```

{% endcode %}

An attacker could make thousands of requests per second to this endpoint:

<mark style="color:red;">`while true; do curl -X POST http://api.example.com/login; done`</mark>

This could lead to:

<kbd>Server overload</kbd> <kbd>Increased costs</kbd> <kbd>Successful brute force attacks</kbd>

## 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.

### Code Samples

{% tabs %}
{% tab title="Node.js/Express" %}
**Vulnerable Code**

```javascript
const express = require('express');
const router = express.Router();

router.get('/', function (req, res) {
    setHeaders(res);
    let params = getSessionParams(req);
    res.render('pages/index', params);
});
```

**Fixed Code**

```javascript
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.).
{% endtab %}

{% tab title="Python/Flask" %}
**Vulnerable Code**

```python
from flask import Flask

@app.route("/api/data")
def get_data():
    return jsonify({"data": "sensitive information"})
```

**Fixed Code**

```python
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.
{% endtab %}

{% tab title="Java/Spring" %}
**Vulnerable Code**

```java
@RestController
public class ApiController {
    @GetMapping("/api/resource")
    public ResponseEntity<?> getResource() {
        return ResponseEntity.ok(resourceService.getData());
    }
}
```

**Fixed Code**

```java
@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.
{% endtab %}

{% tab title="PHP/Laravel" %}
**Vulnerable Code**

```php
Route::post('/api/endpoint', function (Request $request) {
    return response()->json(['status' => 'success']);
});
```

**Fixed Code**

```php
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.
{% endtab %}

{% tab title="Go" %}
**Vulnerable Code**

```go
func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
}

http.HandleFunc("/", handler)
```

**Fixed Code**

```go
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.
{% endtab %}
{% endtabs %}

## Need more help in implementing Rate Limiting?

[Mobb](https://mobb.ai) supports fixing many forms of Missing Rate Limiting vulnerabilities, and can mitigate your issues in batch.

Start now for free at [app.mobb.ai](https://app.mobb.ai)

### We'd love your feedback!

We're excited to hear your thoughts and ideas about fixing vulnerabilities.

[Book a meeting](https://calendly.com/mobbai/demo) or [Contact us](https://content.mobb.ai/contact) if you have any corrections, questions or suggestions. Start now for free at <https://app.mobb.ai>
