Introducción: Por qué la seguridad de las aplicaciones Java no es una opción, sino una necesidad
Java sigue siendo uno de los lenguajes más populares para el desarrollo de 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), las vulnerabilidades en el código provocan cada año filtraciones de datos y pérdidas financieras por miles de millones de dólares. En este artículo, analizaremos el top 10 de vulnerabilidades de aplicaciones Java, mostraremos ejemplos reales de código y daremos recomendaciones concretas para la protección. El material será útil tanto para desarrolladores principiantes como para experimentados que busquen escribir código seguro.
1. Inyecciones: SQL, LDAP y Command Injection
Las inyecciones siguen siendo el rey de las vulnerabilidades. El caso más común es la inyección SQL, cuando la entrada del usuario se concatena directamente en una consulta SQL.
Ejemplo de código vulnerable
String query = "SELECT * FROM users WHERE username = '" + request.getParameter("user") + "'";Statement stmt = connection.createStatement();ResultSet rs = stmt.executeQuery(query);Si un atacante introduce admin' OR '1'='1, obtendrá acceso a todos los usuarios.
Cómo protegerse
- Use PreparedStatement: las consultas parametrizadas escapan automáticamente la entrada.
- Valide los datos de entrada en el lado del servidor (listas blancas).
- Para LDAP y comandos del sistema operativo, aplique escape y evite llamar a
Runtime.exec()con datos del usuario.
// Versión seguraString query = "SELECT * FROM users WHERE username = ?";PreparedStatement pstmt = connection.prepareStatement(query);pstmt.setString(1, request.getParameter("user"));ResultSet rs = pstmt.executeQuery();2. Fallos en la autenticación y gestión de sesiones
La autenticación débil es la segunda vulnerabilidad más peligrosa. A menudo se encuentran: ausencia de límite en el número de intentos de inicio de sesión, almacenamiento de contraseñas en texto plano, session ID predecibles.
Recomendaciones
- Almacene las contraseñas solo como hashes con sal (por ejemplo, bcrypt o Argon2).
- Use
SecureRandompara generar tokens de sesión. - Establezca tiempos de espera de sesión y un mecanismo de "recordarme" con un token seguro.
// Generación de un session ID seguroimport java.security.SecureRandom;String sessionId = new SecureRandom().ints(48, 122) .filter(i -> Character.isLetterOrDigit(i)) .limit(64) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) .toString();3. XSS (Cross-Site Scripting)
XSS permite inyectar JavaScript malicioso en una página que otros usuarios están viendo. Esto es especialmente peligroso para aplicaciones web en Java con JSP o Thymeleaf.
Ejemplo de vulnerabilidad
<div>${userComment}</div>Si userComment contiene <script>alert('XSS')</script>, el código se ejecutará en el navegador.
Protección
- Escape la salida: en JSP use
c:outofn:escapeXml(). - Para Thymeleaf —
th:utextes peligroso, useth:text. - Aplique cabeceras de Content Security Policy (CSP).
4. Deserialización insegura
La deserialización en Java es una de las vulnerabilidades más críticas, que permite la ejecución de código arbitrario (RCE). Un atacante puede manipular el flujo de bytes e inyectar un objeto malicioso.
Ejemplo de ataque
ObjectInputStream ois = new ObjectInputStream(request.getInputStream());Object obj = ois.readObject(); // ¡Peligro!Cómo protegerse
- No deserialice