Careeroza
OWASP Top 10 for Spring Apps
The List and the Spring Fix
The OWASP Top 10 is the industry list of the most common web application risks. Here is each one with what to do in a Spring Boot app:
| # | Risk | Spring Boot defence |
|---|---|---|
| A01 | Broken Access Control (IDOR, missing checks) | deny by default (anyRequest().authenticated()), ownership checks with @PreAuthorize/@PostAuthorize, access-matrix tests |
| A02 | Cryptographic Failures | HTTPS + HSTS, BCrypt/Argon2 for passwords, encrypt sensitive columns, no secrets in tokens |
| A03 | Injection (SQL, JPQL, command) | Spring Data / JPA parameters, never concatenate SQL; Bean Validation on input |
| A04 | Insecure Design | threat modelling, rate limits, business rules (max quantity, price from DB not client) |
| A05 | Security Misconfiguration | no default passwords, Actuator locked down, error pages without stack traces, security headers |
| A06 | Vulnerable and Outdated Components | keep Spring Boot patched, OWASP Dependency-Check / Dependabot / Snyk in CI |
| A07 | Identification and Authentication Failures | MFA, lockout + rate limiting, short-lived tokens, session fixation protection (default on) |
| A08 | Software and Data Integrity Failures | signed artifacts, verified CI pipelines, no Java deserialization of untrusted data |
| A09 | Security Logging and Monitoring Failures | audit logins and access denials, alerts on spikes |
| A10 | Server-Side Request Forgery (SSRF) | allow-list hosts when fetching user-supplied URLs (e.g. "import product image from URL") |
A01 in Practice: Never Trust the Client
// BAD: customerId and price come from the request
@PostMapping("/api/orders")
public Order place(@RequestBody OrderRequest req) {
return orderService.create(req.customerId(), req.items(), req.totalPrice());
}
// GOOD: identity from the token, prices from the database
@PostMapping("/api/orders")
public OrderDto place(@AuthenticationPrincipal Jwt jwt, @Valid @RequestBody PlaceOrderRequest req) {
return orderService.create(jwt.getSubject(), req.items()); // service loads each Product.price itself
}A05: Lock Down Actuator
application-prod.yml
management:
endpoints:
web:
exposure:
include: health, info, prometheus # never "*" in production
endpoint:
health:
show-details: when-authorized
server:
error:
include-stacktrace: never
include-message: never.requestMatchers(EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class)).permitAll()
.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("OPS")Note: An exposed /actuator/heapdump or /actuator/env leaks database passwords and live session tokens. It is one of the most common real-world Spring Boot breaches.