Slide 20 of 28
Part 4 · PreventionSlide 20
Slide 20 · Mitigation 2
MIT 02
Enforce a server-side maximum on paginated results — ignore what the client requests.

For every endpoint that returns a list of records, define a maximum page size. The server enforces it regardless of what the client sends. If the client requests limit=999999, the server returns at most max_limit records and indicates there are more pages.

# Vulnerable: trust the client's limit parameter results = db.query("SELECT * FROM users LIMIT ?", params["limit"]) # Fixed: cap at server's max regardless of what client requests MAX_PAGE_SIZE = 100 requested = int(params.get("limit", 20)) limit = min(requested, MAX_PAGE_SIZE) results = db.query("SELECT * FROM users LIMIT ?", limit)

The max page size should be based on what a legitimate user case actually needs — not on what the database could return. For user lists, 100 is generous. For search results, 20–50 covers most use cases. For bulk data exports, consider separate authenticated batch endpoints with quotas, not a giant limit on the main search endpoint.

A cap on page size still allows an attacker to paginate through all records by calling the endpoint many times. That's where rate limiting (MIT 01) comes in. Both defenses are needed: max page size prevents one-request DoS, rate limiting prevents systematic enumeration over many requests.

💼 Business takeaway

Ask whether there is a maximum size for requests to your API. An endpoint that accepts payloads without a size limit or returns records without a count limit is a denial-of-service risk.

← Back MIT 03: Payload size limits →