<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: implementing-api-rate-limiting-security
description: >-
  Implement and validate API rate limiting controls to prevent abuse, brute
  force attacks, credential stuffing, and resource exhaustion through proper
  throttling, quota enforcement, and adaptive rate limiting strategies.
domain: cybersecurity
subdomain: api-security
tags:
  - rate-limiting
  - api-security
  - owasp-api4
  - throttling
  - dos-prevention
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1499", "T1110"]
  owasp-api: ["API4"]
  tools: ["curl", "burp-suite", "nuclei", "vegeta"]
---

# Implementing API Rate Limiting Security

## Overview

Unrestricted resource consumption (OWASP API4:2023) allows attackers to
exhaust API resources through excessive requests. Effective rate limiting
must enforce per-user, per-endpoint, and global thresholds while providing
clear feedback via standard HTTP headers.

## Prerequisites

- Tools: ["curl", "burp-suite", "nuclei", "vegeta"]
- Access to API gateway or reverse proxy configuration
- Baseline traffic metrics for threshold calibration
- Authorized testing engagement with written scope

## Key Concepts

- **Fixed window**: Count requests per fixed time interval
- **Sliding window**: Rolling time window for smoother enforcement
- **Token bucket**: Burst-tolerant with sustained rate limit
- **Adaptive limiting**: Dynamic thresholds based on behavior scoring

## Workflow

### Step 1: Audit Existing Rate Limits

```bash
# Check rate limit headers in response
curl -sI -H "Authorization: Bearer $TOKEN" \
  https://target.com/api/users/me | grep -iE 'rate|limit|retry|x-ratelimit'

# Expected headers: X-RateLimit-Limit, X-RateLimit-Remaining,
# X-RateLimit-Reset, Retry-After

# Rapid-fire to trigger rate limiting
for i in $(seq 1 200); do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    -H "Authorization: Bearer $TOKEN" \
    "https://target.com/api/users/me")
  echo "Request $i: HTTP $STATUS"
  [ "$STATUS" = "429" ] && echo "Rate limited at request $i" && break
done
```

### Step 2: Test Rate Limit Bypass Techniques

```bash
# IP rotation via headers
for HEADER in X-Forwarded-For X-Real-IP X-Originating-IP \
  X-Client-IP CF-Connecting-IP True-Client-IP; do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    -H "$HEADER: 1.2.3.4" \
    -H "Authorization: Bearer $TOKEN" \
    "https://target.com/api/login")
  echo "$HEADER: HTTP $STATUS"
done

# HTTP method switching
for METHOD in GET POST PUT PATCH; do
  curl -s -o /dev/null -w "$METHOD: %{http_code}\n" \
    -X "$METHOD" "https://target.com/api/data"
done

# Path manipulation to bypass per-endpoint limits
PATHS=(
  "/api/users/me"
  "/api/users/me/"
  "/api/users/me?"
  "/api/./users/me"
  "/API/USERS/ME"
)
for P in "${PATHS[@]}"; do
  curl -s -o /dev/null -w "$P: %{http_code}\n" \
    -H "Authorization: Bearer $TOKEN" \
    "https://target.com$P"
done
```

### Step 3: Load Testing with vegeta

```bash
# Sustained load test to find rate limit threshold
echo "GET https://target.com/api/data" | \
  vegeta attack -rate=50/s -duration=30s \
    -header "Authorization: Bearer $TOKEN" | \
  vegeta report

# Analyze status code distribution
echo "GET https://target.com/api/data" | \
  vegeta attack -rate=100/s -duration=10s \
    -header "Authorization: Bearer $TOKEN" | \
  vegeta report -type=text | grep -E 'Status Codes|Success'
```

### Step 4: Validate Authentication Endpoint Limits

```bash
# Brute force login to verify rate limiting
for i in $(seq 1 50); do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    -X POST -H "Content-Type: application/json" \
    -d "{\"email\":\"user@test.com\",\"password\":\"wrong$i\"}" \
    "https://target.com/api/login")
  echo "Attempt $i: HTTP $STATUS"
  [ "$STATUS" = "429" ] && echo "Login rate limited at attempt $i" && break
done

# Test password reset endpoint throttling
for i in $(seq 1 20); do
  curl -s -o /dev/null -w "Reset $i: %{http_code}\n" \
    -X POST -H "Content-Type: application/json" \
    -d '{"email":"user@test.com"}' \
    "https://target.com/api/password-reset"
done
```

## Detection Opportunities

| Signal | Source | Description |
|--------|--------|-------------|
| High request volume | API gateway | Single client exceeding normal patterns |
| Rate limit bypass headers | WAF logs | X-Forwarded-For manipulation attempts |
| Authentication spraying | Auth logs | Many failed logins from one source |
| 429 response spikes | Metrics | Rate limiting triggering frequently |

```yaml
title: Rate Limit Bypass Attempt via IP Header Spoofing
id: c3d4e5f6-a7b8-9012-cdef-123456789012
status: experimental
description: Detects requests using IP spoofing headers to bypass rate limits
logsource:
  category: webserver
detection:
  selection:
    cs-header-names|contains:
      - 'X-Forwarded-For'
      - 'X-Real-IP'
      - 'X-Originating-IP'
      - 'True-Client-IP'
  filter:
    cs-header-X-Forwarded-For|cidr:
      - '10.0.0.0/8'
      - '172.16.0.0/12'
      - '192.168.0.0/16'
  condition: selection and not filter
falsepositives:
  - Legitimate proxy chains with multiple forwarded-for headers
level: medium
tags:
  - attack.t1499
  - attack.impact
```

## Verification

- [ ] Rate limit headers present on all endpoints (X-RateLimit-*)
- [ ] 429 returned when limit exceeded with Retry-After header
- [ ] Authentication endpoints have strict per-account limits
- [ ] IP header bypass techniques blocked
- [ ] Path normalization prevents per-endpoint bypass
- [ ] Load test confirms limits enforce correctly under sustained traffic

## References

- [OWASP API4:2023 — Unrestricted Resource Consumption](https://owasp.org/API-Security/editions/2023/en/0xa4-unrestricted-resource-consumption/)
- [IETF RFC 6585 — 429 Too Many Requests](https://www.rfc-editor.org/rfc/rfc6585#section-4)
- [MITRE ATT&CK T1499 — Endpoint Denial of Service](https://attack.mitre.org/techniques/T1499/)
