Review of OWASP Top 10 2025 for Java
February 24, 2026Β·260 views

πŸ›  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

#devsecops#toolchain#sast#dast#secretmanagement#specialty#appsec
Open in Telegram