mediumCWE-770A04:2021

Missing Pagination on Data Endpoints

API endpoints that return all matching records without pagination or limit, enabling attackers to dump entire tables and causing memory/performance issues under normal load.

How It Works

Without LIMIT, `SELECT * FROM users` on a table with 10 million records will try to load all 10 million into memory and return them in a single response. Even with a few thousand records, this blocks your server thread, exhausts memory, and leaks your entire dataset to anyone who calls the endpoint.

Vulnerable Code
// BAD: no LIMIT on the query
export async function GET() {
  const users = await db.users.findMany(); // returns ALL users
  return Response.json(users);
}
Secure Code
// GOOD: enforce pagination with cursor or offset
export async function GET(req: Request) {
  const { searchParams } = new URL(req.url);
  const cursor = searchParams.get('cursor');
  const limit = Math.min(parseInt(searchParams.get('limit') ?? '20'), 100);
  const users = await db.users.findMany({
    take: limit,
    cursor: cursor ? { id: cursor } : undefined,
    orderBy: { id: 'asc' }
  });
  return Response.json(users);
}

Real-World Example

A SaaS product's /api/customers endpoint had no pagination. A competitor wrote a script to call it repeatedly (it returned all customers in one shot due to a missing WHERE clause), downloaded the entire customer list, and used it for competitive poaching.

How to Prevent It

  • Always apply a maximum LIMIT/take to database queries in API endpoints
  • Implement cursor-based or offset-based pagination for list endpoints
  • Let callers control page size but enforce a maximum (e.g., 100 records)
  • Never expose endpoints that can return unbounded result sets

Affected Technologies

nodejsNext.jsPythonGo

Data Hogo detects this vulnerability automatically.

Scan Your Repo Free

Related Vulnerabilities