Require Authorization on Every Spring Boot Endpoint
Flags Spring Boot endpoints with no authorization rule, broad permitAll() matchers, ignored method security, and lookups by ID without ownership checks.
What it flags
@RestController
@RequestMapping("/api/invoices")
public class InvoiceController {
private final InvoiceRepository invoices;
public InvoiceController(InvoiceRepository invoices) {
this.invoices = invoices;
}
@GetMapping("/{id}")
public InvoiceResponse get(@PathVariable Long id) {
// Any signed-in user can read any invoice by changing the id
return invoices.findById(id)
.map(InvoiceResponse::from)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
}
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id) {
invoices.deleteById(id);
}
}@RestController
@RequestMapping("/api/invoices")
public class InvoiceController {
private final InvoiceRepository invoices;
public InvoiceController(InvoiceRepository invoices) {
this.invoices = invoices;
}
@GetMapping("/{id}")
public InvoiceResponse get(@PathVariable Long id, @AuthenticationPrincipal AppUser user) {
return InvoiceResponse.from(findOwned(id, user));
}
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('BILLING_ADMIN')") // SecurityConfig declares @EnableMethodSecurity
public void delete(@PathVariable Long id, @AuthenticationPrincipal AppUser user) {
invoices.delete(findOwned(id, user));
}
private Invoice findOwned(Long id, AppUser user) {
return invoices.findByIdAndAccountId(id, user.getAccountId())
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
}
}Why it matters
Spring Security applies the first matching rule in authorizeHttpRequests, so one broad permitAll() added for a public route can open every endpoint beneath it. @PreAuthorize without @EnableMethodSecurity compiles and looks protected while enforcing nothing. Missing ownership checks let an authenticated user read or delete another customer's record by changing an ID in the URL; broken object-level authorization is the first item in the OWASP API Security Top 10.
Agent instructions
cubic checks every pull request against these instructions. Paste them into AGENTS.md or Cursor rules and your AI coding tool follows them while it writes code.
AGENTS.md
Add this section to AGENTS.md at the repository root. Codex, Cursor, and other AI coding tools read it.
## Require Authorization on Every Spring Boot Endpoint Applies to `**/*.java`. Review Spring Security configuration and controller endpoints for requests that reach business logic without an authorization decision. Flag changes that: - Add admin, internal, or data-changing endpoints protected only by `anyRequest().authenticated()`, with no role rule, `@PreAuthorize`, `@Secured`, or other authorization check. - Add broad `permitAll()` matchers such as `"/api/**"` or `"/**"`, or place a `permitAll()` rule before a more specific restriction. `authorizeHttpRequests` applies the first rule that matches. - End the rules with `anyRequest().permitAll()` instead of `anyRequest().authenticated()` or `denyAll()`. - Use `web.ignoring()` in a `WebSecurityCustomizer` for application endpoints, which removes them from the Spring Security filter chain. - Use `@PreAuthorize` or `@PostAuthorize` in an application that enables neither `@EnableMethodSecurity` nor, on Spring Security 5, `@EnableGlobalMethodSecurity(prePostEnabled = true)`, or use `@Secured` without `securedEnabled = true` on whichever of the two it uses, so the annotations are never enforced. - Load, update, or delete a record by a client-supplied ID, such as `findById(id)` or `deleteById(id)`, without checking that it belongs to the current user, account, or tenant. Do not flag: - Endpoints that are public by design and listed explicitly, such as login, health checks, static assets, or webhook receivers that verify a signature. - Endpoints already covered by a path rule that requires the needed role or authority. - Lookups scoped to the principal, such as `findByIdAndAccountId(id, user.getAccountId())`, or guarded by a `@PreAuthorize` or `@PostAuthorize` ownership expression.
Checks files matching **/*.java.
More Spring Boot agents
See all Spring Boot code review standards
Run this agent on every pull request
cubic reviews every pull request against the agents you turn on and comments on the lines that break them.