Introducción: ¿Por qué es crítica la seguridad de las aplicaciones Java?
Java sigue siendo uno de los lenguajes más populares para crear aplicaciones empresariales y web. Sin embargo, la popularidad conlleva una mayor atención por parte de los atacantes. Según OWASP (Open Web Application Security Project), la mayoría de las intrusiones ocurren debido a errores típicos de los desarrolladores, y no por vulnerabilidades de la propia plataforma. En este artículo, analizaremos las 10 vulnerabilidades más peligrosas de las aplicaciones Java, mostraremos ejemplos de código y daremos recomendaciones prácticas para la protección.
1. Inyección SQL (SQL Injection)
Problema: Transmisión de datos de usuario no verificados en una consulta SQL.
Ejemplo de código vulnerable:
String query = "SELECT * FROM users WHERE username = '" + userInput + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
Solución: Utilice consultas parametrizadas (PreparedStatement).
String query = "SELECT * FROM users WHERE username = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, userInput);
ResultSet rs = pstmt.executeQuery();
2. Cross-Site Scripting (XSS)
Problema: Inserción de scripts maliciosos en una página web a través de la entrada del usuario.
Ejemplo de vulnerabilidad:
String comment = request.getParameter("comment");
out.println("<div>" + comment + "</div>");
Solución: Escapar los caracteres HTML. Utilice bibliotecas como OWASP Java Encoder.
import org.owasp.encoder.Encode;
String comment = request.getParameter("comment");
out.println("<div>" + Encode.forHtml(comment) + "</div>");
3. Deserialización insegura
Problema: Un atacante puede enviar un objeto serializado que, al deserializarse, ejecutará código arbitrario.
Ejemplo:
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object obj = ois.readObject(); // ¡Peligroso!
Solución:
- No deserialice datos de fuentes no confiables.
- Utilice listas blancas de clases (look-ahead deserialization).
- Aplique JSON (Jackson) con configuraciones de seguridad.
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); // ¡Inseguro!
// Correcto: deshabilitar defaultTyping y usar @JsonTypeInfo
4. Cross-Site Request Forgery (CSRF)
Problema: Un atacante obliga al usuario a realizar una acción no deseada en un sitio de confianza.
Solución: Utilice tokens CSRF. En Spring Security esto está integrado:
<form action="/transfer" method="post">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<input type="text" name="amount"/>
<button type="submit">Transferir</button>
</form>
5. Fallos de autenticación y gestión de sesiones
Problemas: Contraseñas débiles, cookies no protegidas, sesiones fijas.
Recomendaciones:
- Utilice bcrypt o Argon2 para el hash de contraseñas.
- Establezca las banderas
HttpOnlyySecurepara las cookies. - Implemente el bloqueo después de N intentos de inicio de sesión fallidos.
PasswordEncoder encoder = new BCryptPasswordEncoder();
String hashedPassword = encoder.encode(plainPassword);
6. Configuración de seguridad incorrecta (Security Misconfiguration)
Problema: Modos de depuración habilitados, contraseñas predeterminadas, endpoints no protegidos.
Solución: