π Review of OWASP Top 10 2025 for Java
Salute,
You and I recently started looking towards OWASP TOP 10 (here) for Semgrep rules.
I think it would be cool to do a review on OWASP with specifics for Java, where I can further show why itβs cool in a custom way for this language. Moreover, Iβm currently preparing a resource project for Semgrep, so letβs make it together more useful if youβre in JAVA, or work with it somehow related (and in general, you can reuse constructs for other languages).
Now let's look at the main types with examples
A01:2025 β Broken Access Control
Access violation - there is no restriction on user actions beyond their authority - actions without authorization
// There is no owner check, hence user `id=123` is changed to `id=124` and receives information without any checks
public Order getOrder(@PathVariable Long id) {
return orderRepository.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
}
A02:2025 β Security Misconfiguration
Incorrect configuration - insecure default settings, open Actuator-endpoints, disabled security headers
A03:2025 β Software Supply Chain Failures
Supply chain failures - vulnerable dependencies, pipelines without checks and verification of artifacts, compromised repositories, Maven/Gradle repositories over direct HTTP, lack of checksum verification, snapshot in prod
A04:2025 β Cryptographic Failures
Cryptographic failures - weak algorithms, primitive hashing, insufficient key lengths
// MD5 without salt, rainbow tables are hacked
String hash = DigestUtils.md5Hex(password);
userRepository.save(new User(username, hash));
A05:2025 β Injection
Injections - injection without sanitization such as FreeMarker, Velocity, Thymeleaf, JNDI
// String concatenation in SQL
String query = "SELECT * FROM users WHERE username = '" + username + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
A06:2025 β Insecure Design
Unsafe design - problems are inherent at the architectural level: no rate limit, no logic checks, fail-safe is not provided
// There are no rate limits on the password and the attacker tries OTP without restrictions
public ResponseEntity<?> resetPassword(@RequestBody ResetRequest req){
return passwordService.reset(req.getEmail(), req.getOtp());
}
A07:2025 β Authentication Failures
Authentication failures - weak passwords, lack of MFA, insecure sessions, lack of brute force protection, insecure storage of credentials
// JWT is accepted without signature verification
Claims claims = Jwts.parser()
.parse(token)
.getBody();
String role = claims.get("role", String.class);
A08:2025 β Software or Data Integrity Failures
Integrity failures - deserialization of objects without declaring restrictions, lack of signature verification, disabled verification of TLS certificates, JNDI injection, HTTP updates without hash verification
// Deserialization without a type filter, RCE is possible via gadget chains
ObjectInputStream ois = new ObjectInputStream(request.getInputStream());
Object obj = ois.readObject();
A09:2025 β Security Logging & Alerting Failures
Logging failures - lack of recording of information security events, such as failed logins, access denied, privilege escalation, logging of passwords and tokens in clear text, lack of alerts for SIEM
A10:2025 β Mishandling of Exceptional Conditions
Incorrect exception handling - empty catch blocks, stacktrace in HTTP responses, fail-open behavior, i.e. returning true on an exception, loss of exceptions in async code, incorrect HTTP status error codes
public boolean isAuthorized(String token) {
try {
return jwtService.verify(token);
} catch (Exception e) {
return true; // gain access
}
}
#devsecops #toolchain #sast #dast #secretmanagement #specialty #appsec
