Broken Access Control Prevention in Spring Boot – OWASP A01
Fast recall
Quick revision
Core answer
/orders/101 to /orders/102, calling an admin action as a normal user, or trusting a tenant ID from the request. In Spring Boot, deny by default, protect requests and methods, scope database access to the current principal or tenant, and test horizontal and vertical privilege changes. Authentication alone is not authorization.Interview-ready guide
Interview answer
Broken Access Control is when users can access resources or perform actions they shouldn't be authorized for.
It's the number one OWASP risk in 2021 because it's incredibly common and easy to exploit. The classic example is IDOR, which stands for Insecure Direct Object Reference. Imagine your API has an endpoint like GET /api/orders/123.
If you only check that the user is logged in but don't verify they actually own order 123, an attacker can just change the ID to 124, 125, and keep going to view everyone's orders. In Spring Boot, freshers often think securing URL patterns in the SecurityFilterChain config is enough. Like they'll do requestMatchers for /api/** dot authenticated and assume they're done.
But that only checks if someone is logged in, not if they can access that specific resource. The fix has two parts. First, use method-level security with at-PreAuthorize on your controller methods.
Second, and this is critical, verify resource ownership in your service layer. You grab the authenticated user with at-AuthenticationPrincipal, fetch the order from the database, and explicitly check if the order's user ID matches the current user's ID. If it doesn't match, throw an AccessDeniedException.
One pitfall is only securing things in the frontend by hiding buttons or links. Attackers don't use your UI—they call your API directly with tools like Postman. Every endpoint must enforce authorization server-side, every single time.
Broken Access Control Prevention in Spring Boot – OWASP A01
Direct Answer
Broken Access Control means the server lets a principal read data or perform an action outside its permissions. Examples include changing /orders/101 to /orders/102, calling an admin action as a normal user, or trusting a tenant ID from the request. In Spring Boot, deny by default, protect requests and methods, scope database access to the current principal or tenant, and test horizontal and vertical privilege changes. Authentication alone is not authorization.
Code Example
@RestController
@RequestMapping("/api/orders")
class OrderController {
private final OrderService orders;
@GetMapping("/{id}")
@PreAuthorize("isAuthenticated()")
OrderDto get(@PathVariable long id, Authentication auth) {
return orders.findForUser(id, auth.getName());
}
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('ADMIN')")
void delete(@PathVariable long id) {
orders.delete(id);
}
}
@Service
class OrderService {
OrderDto findForUser(long id, String username) {
return repository.findByIdAndUsername(id, username)
.map(OrderDto::from)
.orElseThrow(ResourceNotFoundException::new);
}
}
The user-controlled ID is not trusted by itself; the query includes the current principal. Administrative policy remains a separate explicit check.
Common Mistakes & Pitfalls
- URL-Level Security Only: Configuring
.requestMatchers("/api/**").authenticated()in SecurityFilterChain and believing all endpoints are now secure—this only verifies someone is logged in, not whether they can access specific resources. - Trusting Client Input: Taking an order ID from the request and immediately querying the database without ownership verification, allowing attackers to iterate through IDs and access all orders.
- Hidden Through Obscurity: Removing links from the UI for unauthorized actions but leaving the actual API endpoints unprotected—attackers don't need your UI, they call APIs directly with Postman.
- Checking Authorization in Frontend Only: Disabling delete buttons for non-admins in React but having
/api/orders/123/deleteaccept requests from anyone authenticated—UI controls are not security controls.
Check your understanding
Answer these without looking back at the article.
- What is IDOR and give a concrete example of the attack?
- How would you implement ownership verification for a multi-tenant API?
- What is the principle of least privilege?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.