Login
ChallengesLearn
Scoreboard
Teams
SPNZ

LearnAPI SecurityAPI Rate Limiting & Abuse
API Security·Lesson 7 of 11

API Rate Limiting & Abuse

OWASP API #4 & #5. Brute-force login via API (no rate limit = unlimited attempts), resource exhaustion via pagination abuse, GraphQL deep query cost attacks, and how API gateways throttle.

Advanced14 min
APIRate LimitingAbuse
Loading lesson…
PreviousAPI Mass AssignmentNextAPI Automated Security Testing

© 2026 SPNZ.

Terms of ServicePrivacy PolicyCookie Policy

APIs do not fail secure by default. OWASP API Security Top 10 ranks Unrestricted Resource Consumption (API #4) and Broken Function Level Authorization (API #5) among the most frequently exploited API flaws. Without rate limiting and proper authorisation checks, a single endpoint can bring down a database, leak millions of records, or let attackers impersonate administrators.

What you'll be able to do
  • Explain why rate limiting is necessary at the API layer, not just the network layer.
  • Identify attack patterns that exploit missing or weak rate limits.
  • Describe how broken function level authorisation lets attackers escalate privileges.
  • Apply mitigation techniques including token bucket, query depth limiting, and pagination caps.
Key terms
Rate limiting
A mechanism that controls how many requests a client can make within a given time window. Without it, APIs are vulnerable to resource exhaustion, credential stuffing, and denial of service.
Token bucket algorithm
A rate-limiting algorithm where tokens are added to a bucket at a fixed rate. Each request consumes a token. If the bucket is empty, the request is denied. Bursts are allowed up to the bucket capacity.
GraphQL depth/cost limiting
Restricting the maximum nesting depth or computational cost of a GraphQL query. Without these limits, a single query can trigger exponential database load through nested field resolution.
Broken Function Level Authorisation
An authorisation failure where an API endpoint intended for administrators is accessible to regular users, often because the endpoint relies on obscurity rather than a role check.
What is it?

Rate limiting failure and broken authorisation

Rate limiting failure (OWASP API #4) occurs when an API does not cap the number of requests a client can make. This opens the door to credential stuffing — attackers try thousands of username/password pairs against a login endpoint — and resource exhaustion, where a single client floods the database with expensive queries. A common vector is pagination abuse: sending requests like ?page=1000&limit=100 forces the database to scan and offset millions of rows on every request.

Broken Function Level Authorisation (OWASP API #5) is different but equally dangerous. An API might expose an admin panel at /api/admin/users without checking whether the caller has an admin role. Attackers discover these endpoints through enumeration, JS source inspection, or leaked API documentation. Once found, they can delete users, modify permissions, or exfiltrate data without authentication bypass — just a missing role check.

GraphQL APIs introduce a third class of abuse: cost attacks. A query like friends { friends { friends { ... } } } can nest arbitrarily deep. Without depth limiting or cost analysis, a single request can trigger hundreds of database queries and exhaust server resources.

Rate limiting and authorisation flow
Mini Map
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.
Try it

API rate limit abuse simulator

Try sending requests to a simulated API endpoint. Watch the rate limit counter increase and see what happens when you exceed the threshold. Can you find the hidden admin endpoint?

~/projects/api-abuse-testerprod
api-abuse-tester · rate limit probe

API Rate Limit Tester

Send requests to a simulated API and observe rate limiting in action.

Rate limit status0/8 used
0
Window ready
Request log

No requests yet.

Real-world relevance

T-Mobile 2021 — 37 million accounts exposed

In August 2021, attackers exploited an API rate limiting failure in T-Mobile's customer portal. The API endpoint used for account PIN verification did not enforce any request cap, allowing the attackers to brute-force PINs — a four-digit numeric code — by sending thousands of requests per minute. Once they had the correct PIN for an account, they could access the customer's name, date of birth, billing address, and Social Security number.

The breach exposed personal data for approximately 37 million current and former T-Mobile customers. The root cause was not an authentication bypass or SQL injection — it was the absence of rate limiting on an API endpoint that should have been locked down to a few attempts per minute. T-Mobile later implemented per-endpoint rate limits and introduced CAPTCHA on sensitive endpoints, but the damage had already been done.

This case is a textbook example of OWASP API #4: Unrestricted Resource Consumption. The endpoint was functional and the authorisation logic was correct — the PIN was verified server-side — but the lack of a rate limit turned a cryptographically sound verification into a brute-force target. A token bucket rate limiter set to 5 requests per minute would have made the attack impractical.

Mitigation

Rate limiting and authorisation hardening

Mitigation requires defence in depth at three layers: the API gateway, the application server, and the database. The gateway should enforce per-endpoint rate limits using the token bucket algorithm, with different limits for authenticated and unauthenticated users. The application server must check function-level authorisation on every endpoint, ideally through middleware that maps each route to a required role or permission.

typescriptsafe
// Token bucket rate limiter (middleware)
const buckets = new Map<string, { tokens: number; lastRefill: number }>();

function rateLimit(endpoint: string, maxTokens = 10, refillPerSec = 1) {
  const key = endpoint;
  let bucket = buckets.get(key);
  if (!bucket) {
    bucket = { tokens: maxTokens, lastRefill: Date.now() };
    buckets.set(key, bucket);
  }
  const elapsed = (Date.now() - bucket.lastRefill) / 1000;
  bucket.tokens = Math.min(maxTokens, bucket.tokens + elapsed * refillPerSec);
  bucket.lastRefill = Date.now();
  if (bucket.tokens < 1) {
    return { status: 429, body: 'Too Many Requests' };
  }
  bucket.tokens -= 1;
  return { status: 200 };
}

// Function-level authorisation middleware
function requireRole(role: 'user' | 'admin' | 'super_admin') {
  return (req: Request, res: Response, next: NextFunction) => {
    const userRole = req.user?.role;
    if (!userRole || userRole !== role) {
      return res.status(403).json({ error: 'Forbidden' });
    }
    next();
  };
}

// GraphQL depth limiter
function limitQueryDepth(document: DocumentNode, maxDepth = 5): boolean {
  function depth(selectionSet: SelectionSetNode, d: number): number {
    if (d > maxDepth) return d;
    return Math.max(...selectionSet.selections.map((sel) =>
      sel.kind === 'Field' && sel.selectionSet
        ? depth(sel.selectionSet, d + 1)
        : d
    ));
  }
  return depth(document.definitions[0] as any, 1) <= maxDepth;
}

// Pagination cap
app.get('/api/items', (req, res) => {
  const page = Math.min(parseInt(req.query.page as string) || 1, 100);
  const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);
  // safe bounded pagination
});
Further reading
  • OWASP API Security Top 10 — API #4 and #5(OWASP)
  • T-Mobile 2021 breach technical analysis(Krebs on Security)
  • Token bucket rate limiting explained(Wikipedia)
  • GraphQL query cost analysis(GraphQL Foundation)
Key takeaways

What to remember

  • Rate limiting must be per-endpoint, not global — login endpoints need stricter limits than read-only endpoints.
  • The token bucket algorithm allows short bursts while capping sustained load, making it ideal for API rate limiting.
  • Broken Function Level Authorisation is not an authentication issue — it is a missing role check on endpoints that assume obscurity equals security.
  • GraphQL APIs need depth limiting, cost analysis, and pagination caps to prevent resource exhaustion via nested queries.
  • The T-Mobile 2021 breach (37 million records) was caused by a missing rate limit on a PIN verification endpoint, not a cryptographic flaw.

Knowledge check

0/3 answered · 0 correct
  1. 1.What is the primary difference between rate limiting failure and broken function level authorisation?

  2. 2.How did attackers exploit T-Mobile's API in the 2021 breach?

  3. 3.Which technique prevents GraphQL resource exhaustion?