HIGH bola idorspring boot

Bola Idor in Spring Boot

How Bola Idor Manifests in Spring Boot

BOLA/IdOR (Broken Object Level Authorization/Insecure Direct Object References) occurs when an application exposes direct references to objects and fails to verify whether the current user has permission to access them. In Spring Boot applications, this vulnerability often emerges through several specific patterns.

The most common manifestation appears in Spring Data JPA repositories where methods like findById() are called without proper authorization checks. Consider this vulnerable controller pattern:

@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    @Autowired
    private OrderRepository orderRepository;
    
    @GetMapping("/{id}")
    public ResponseEntity<Order> getOrder(@PathVariable Long id) {
        // Critical flaw: no authorization check
        Order order = orderRepository.findById(id).orElseThrow();
        return ResponseEntity.ok(order);
    }
}

A malicious user could simply increment the order ID in the URL to access any other user's order data. This pattern is particularly prevalent in Spring Boot because the framework's convention-over-configuration approach makes it easy to write minimal code that works but lacks security.

Another Spring Boot-specific pattern involves using @AuthenticationPrincipal incorrectly or not at all. When developers retrieve the authenticated user but fail to validate ownership:

@GetMapping("/{id}")
public ResponseEntity<Order> getOrder(@PathVariable Long id, 
                                        @AuthenticationPrincipal User user) {
    Order order = orderRepository.findById(id).orElseThrow();
    // Missing: if (!order.getUserId().equals(user.getId())) throw forbidden;
    return ResponseEntity.ok(order);
}

Spring Boot's @PreAuthorize and @PostAuthorize annotations provide declarative security, but developers often omit them, relying instead on method-level security that doesn't exist. This creates a false sense of security where the code appears protected but isn't.

REST controllers using @PathVariable for object identifiers without validation represent another critical vector. Spring Boot's automatic JSON deserialization can also introduce BOLA when entities are directly exposed without filtering sensitive fields:

@GetMapping("/{id}")
public Order getOrder(@PathVariable Long id) { // Returns entire entity
    return orderRepository.findById(id).orElseThrow();
}

The framework's support for H2 database in development environments exacerbates this issue, as developers test with embedded databases and forget to add authorization when deploying to production with user data.

Spring Boot-Specific Detection

Detecting BOLA/IdOR in Spring Boot applications requires both static analysis and dynamic testing approaches. middleBrick's black-box scanning is particularly effective because it can probe endpoints without requiring source code access.

middleBrick tests for BOLA by systematically modifying object identifiers in API requests and observing whether access controls properly restrict data. For a Spring Boot endpoint like:

@GetMapping("/users/{userId}/orders/{orderId}")
public ResponseEntity<Order> getUserOrder(@PathVariable Long userId, 
                                            @PathVariable Long orderId) {
    // No authorization check
    return ResponseEntity.ok(orderRepository.findById(orderId).orElseThrow());
}

middleBrick would test variations like:

GET /api/users/1/orders/100
GET /api/users/999/orders/100  # Different user ID
GET /api/users/1/orders/999  # Different order ID

The scanner identifies whether changing these parameters returns data from other users' accounts, which would indicate a BOLA vulnerability.

For Spring Boot applications using Spring Security, middleBrick also checks for proper @PreAuthorize usage. It can detect patterns where:

  • Authentication is present but authorization is missing
  • Method security annotations are commented out or removed
  • Repository methods are called without service-layer authorization checks

middleBrick's OpenAPI/Swagger analysis is particularly valuable for Spring Boot apps, as many use SpringDoc to auto-generate API documentation. The scanner cross-references endpoint definitions with actual runtime behavior, identifying mismatches between documented security requirements and implemented access controls.

Developers can run middleBrick from the CLI to scan their Spring Boot APIs:

middlebrick scan https://yourapp.com/api

The tool provides a security score with specific findings about BOLA vulnerabilities, including the exact request patterns that triggered the issue and severity ratings based on the sensitivity of exposed data.

Spring Boot-Specific Remediation

Remediating BOLA in Spring Boot requires a defense-in-depth approach using the framework's built-in security features. The most effective pattern is implementing service-layer authorization with Spring Security's method security:

@Service
public class OrderService {
    
    @Autowired
    private OrderRepository orderRepository;
    
    @PreAuthorize("#order.userId == authentication.principal.id")
    public Order getOrder(Long orderId, Long userId) {
        return orderRepository.findByIdAndUserId(orderId, userId)
            .orElseThrow(() -> new OrderNotFoundException(orderId));
    }
}

This ensures the database query itself filters by user ID, preventing unauthorized data retrieval even if authorization checks are bypassed elsewhere.

For repository-level protection, Spring Data JPA provides query methods that include user validation:

public interface OrderRepository extends JpaRepository<Order, Long> {
    Optional<Order> findByIdAndUserId(Long id, Long userId);
    boolean existsByIdAndUserId(Long id, Long userId);
}

The controller then becomes:

@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    @Autowired
    private OrderService orderService;
    
    @GetMapping("/{id}")
    public ResponseEntity<Order> getOrder(@PathVariable Long id,
                                          @AuthenticationPrincipal User user) {
        Order order = orderService.getOrder(id, user.getId());
        return ResponseEntity.ok(order);
    }
}

Spring Boot's @JsonView annotation helps prevent data exposure by controlling which fields are serialized based on the user's role:

public class Views {
    public static class Public {}
    public static class Internal extends Public {}
}

@Entity
public class Order {
    
    @JsonView(Views.Public.class)
    private Long id;
    
    @JsonView(Views.Public.class)
    private String status;
    
    @JsonView(Views.Internal.class)
    private BigDecimal totalAmount;
    
    @JsonView(Views.Internal.class)
    private String customerNotes;
}

@RestController
public class OrderController {
    
    @GetMapping("/{id}")
    @JsonView(Views.Public.class)
    public Order getOrder(@AuthenticationPrincipal User user, 
                          @PathVariable Long id) {
        // Authorization logic here
        return orderRepository.findById(id).orElseThrow();
    }
}

For comprehensive protection, Spring Boot developers should implement a custom permission evaluator:

@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject,
                                Object permission) {
        if (targetDomainObject instanceof Order) {
            Order order = (Order) targetDomainObject;
            User user = (User) authentication.getPrincipal();
            return order.getUserId().equals(user.getId());
        }
        return false;
    }
    
    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId,
                                String targetType, Object permission) {
        if ("Order".equals(targetType)) {
            Order order = orderRepository.findById((Long) targetId).orElse(null);
            return hasPermission(authentication, order, permission);
        }
        return false;
    }
}

This evaluator can be registered in the security configuration and used with @PreAuthorize annotations for fine-grained control over object access permissions.

Related CWEs: bolaAuthorization

CWE IDNameSeverity
CWE-250Execution with Unnecessary Privileges HIGH
CWE-639Insecure Direct Object Reference CRITICAL
CWE-732Incorrect Permission Assignment HIGH

Frequently Asked Questions

How does middleBrick detect BOLA vulnerabilities in Spring Boot applications?
middleBrick performs black-box scanning by systematically modifying object identifiers in API requests. For Spring Boot endpoints, it tests variations of user IDs, order IDs, and other object references to determine if the application properly enforces authorization. The scanner checks whether changing these parameters allows access to other users' data, which would indicate a BOLA vulnerability. It also analyzes OpenAPI/Swagger specs from SpringDoc to cross-reference documented security requirements with actual runtime behavior.
What's the difference between BOLA and IDOR, and how does Spring Boot handle both?
BOLA (Broken Object Level Authorization) and IDOR (Insecure Direct Object References) are closely related - IDOR is essentially the implementation flaw that causes BOLA. In Spring Boot, both manifest when applications expose direct object references (like database IDs in URLs) without proper authorization checks. Spring Boot handles these through method security annotations (@PreAuthorize), repository-level query methods that include user validation, and custom permission evaluators. The framework's @AuthenticationPrincipal annotation helps retrieve the current user, but developers must still implement the actual authorization logic to prevent both BOLA and IDOR vulnerabilities.