OWASP Top 10 Vulnerabilities: A Java Developer's Guide
Introduction
Web application security is more critical than ever. The Open Web Application Security Project (OWASP) Top 10 is the definitive guide to the most critical security risks facing web applications. Whether you're building REST APIs, microservices, or traditional web apps, understanding these vulnerabilities in a Java context is essential.
This guide walks through each OWASP Top 10 vulnerability with practical Java examples and mitigation strategies.
1. Broken Authentication
The Risk: Attackers exploit weak authentication mechanisms to gain unauthorized access to user accounts.
Bad Practice:
// DON'T: Storing plain passwords
String storedPassword = user.getPassword();
if (password.equals(storedPassword)) {
login(user);
}
Better Practice:
// DO: Use bcrypt with Spring Security
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String hashedPassword = encoder.encode(rawPassword);
if (encoder.matches(rawPassword, storedPassword)) {
login(user);
}
Prevention:
- Use strong password hashing (bcrypt, Argon2, PBKDF2)
- Implement MFA/2FA
- Add account lockout after failed attempts
- Use HTTPS for all authentication endpoints
2. Broken Access Control
The Risk: Users can access resources or perform actions beyond their authorization level.
Bad Practice:
// DON'T: Trusting user input for access control
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id); // No authorization check
}
Better Practice:
// DO: Check authorization before processing
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id, Principal principal) {
User currentUser = userService.findByUsername(principal.getName());
User requestedUser = userService.findById(id);
if (!currentUser.equals(requestedUser) && !currentUser.isAdmin()) {
throw new AccessDeniedException("Not authorized");
}
return requestedUser;
}
3. Injection Attacks
The Risk: Attackers inject malicious code through input fields (SQL, LDAP, Command injection).
Bad Practice:
// DON'T: SQL Injection vulnerability
String query = "SELECT * FROM users WHERE email = '" + email + "'";
List<User> users = jdbcTemplate.queryForList(query);
Better Practice:
// DO: Use parameterized queries
String query = "SELECT * FROM users WHERE email = ?";
List<User> users = jdbcTemplate.queryForList(query, email);
// Or with JPA
List<User> users = userRepository.findByEmail(email);
4. Insecure Design
The Risk: Missing security controls at the design phase lead to cascading vulnerabilities.
Best Practices:
- Conduct threat modeling during design
- Implement security by default
- Use principle of least privilege
- Separate concerns and sandbox components
// Example: Rate limiting design
@Component
public class RateLimitingAspect {
private final RateLimiter rateLimiter = RateLimiter.create(10.0); // 10 requests/second
@Around("@annotation(RateLimit)")
public Object rateLimit(ProceedingJoinPoint joinPoint) throws Throwable {
if (!rateLimiter.tryAcquire()) {
throw new TooManyRequestsException("Rate limit exceeded");
}
return joinPoint.proceed();
}
}
5. Security Misconfiguration
The Risk: Insecure default configurations, incomplete setups, or exposed settings.
Prevention:
// Security configuration in Spring Boot
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requiresChannel()
.anyRequest()
.requiresSecure() // Force HTTPS
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.headers()
.xssProtection()
.and()
.contentSecurityPolicy("default-src 'self'");
}
}
6. Vulnerable and Outdated Components
The Risk: Using libraries with known vulnerabilities.
Prevention:
- Use Maven/Gradle dependency management
- Regularly update dependencies
- Monitor CVE databases
- Use tools like OWASP Dependency-Check
<!-- pom.xml -->
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>8.0.0</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
7. Identification and Authentication Failures
The Risk: Poor session management, weak password policies, and compromised credentials.
Best Practice:
// Implement proper session management
@Configuration
@EnableWebSecurity
public class SessionSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionFixationProtection(SessionFixationProtectionStrategy.MIGRATEOSESSION)
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.maximumSessions(1) // Only one session per user
.expiredUrl("/login?expired");
}
}
8. Software and Data Integrity Failures
The Risk: Insecure CI/CD pipelines, unsigned updates, and data corruption.
Prevention:
- Digitally sign code and artifacts
- Verify signatures before deployment
- Secure CI/CD pipelines
- Implement integrity checks
9. Logging and Monitoring Failures
The Risk: Insufficient logging makes breach detection impossible.
Best Practice:
// Structured logging with SLF4J
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
public void loginUser(String username) {
try {
// Authentication logic
logger.info("User login successful",
Map.of("username", username, "timestamp", LocalDateTime.now()));
} catch (Exception e) {
logger.warn("Failed login attempt",
Map.of("username", username, "error", e.getMessage()));
}
}
10. Server-Side Request Forgery (SSRF)
The Risk: Application fetches remote resources without validating URLs.
Bad Practice:
// DON'T: Fetch arbitrary URLs
String url = request.getParameter("imageUrl");
InputStream is = new URL(url).openStream(); // Dangerous!
Better Practice:
// DO: Validate URLs against whitelist
private static final Set<String> ALLOWED_HOSTS = Set.of("trusted-cdn.com", "api.example.com");
public InputStream fetchResource(String urlString) throws MalformedURLException {
URL url = new URL(urlString);
if (!ALLOWED_HOSTS.contains(url.getHost())) {
throw new SecurityException("Host not whitelisted");
}
return url.openStream();
}
Conclusion
The OWASP Top 10 represents the most critical risks to web applications. By understanding these vulnerabilities and implementing the recommended practices in your Java applications, you significantly improve your security posture. Remember: security is not a feature—it's a fundamental requirement.
Stay vigilant, keep your dependencies updated, and always validate user input.












