Scenario: an API leaks other customers' orders Intermediate
Estimated reading time: 1 min read
A researcher only has to change a number in the URL to read another customer’s order. While fixing it, the team finds a second hole: a regular user can promote themselves to admin.
You have four decisions: plug the hole, scope who was exposed, fix the design, and close the incident.
- The question to answer at every step: does the caller have rights to this object, and to this field?
- Scoring counts only your first choice at each step.
Change a number in the URL and you can read someone else's order
You are the backend lead of an online shop: 184,000 customers, about 1.2 million orders, order IDs are sequential integers. The API is written in NestJS + PostgreSQL, and access logs are kept for 90 days. Each choice immediately shows its consequences on the metrics.
Step 1/4 · A report from a security researcher
10:05 on Friday, the security@ inbox receives an email from a researcher: logged in with his own account, he called GET /api/orders/1048213, changed the last digit, and the API returned another customer's order: name, phone number, address, items. You reproduce it in 2 minutes.
- bug class
- BOLA / IDOR (OWASP API1:2023)
- order ID
- sequential integer, guessable
- endpoint exists since
- 14 months ago
// orders.controller.ts
@UseGuards(JwtAuthGuard) // only checks that the token is valid
@Get(':id')
get(@Param('id') id: string) {
return this.orders.findById(id); // SELECT * FROM orders WHERE id = $1
}What do you do?
After playing, read BOLA/IDOR to see how to scope queries by actor and which list, bulk and export endpoints tend to get missed.