OWASP Top 10: Las Vulnerabilidades Web Mas Criticas y Como Prevenirlas

Conoce las vulnerabilidades más peligrosas que amenazan las aplicaciones web y aprende a proteger tu código contra cada una de ellas.

Introducción a OWASP

OWASP (Open Web Application Security Project) es una organización sin ánimo de lucro dedicada a mejorar la seguridad del software. Su proyecto más conocido es el OWASP Top 10, una lista actualizada periódicamente con las diez vulnerabilidades de seguridad web más críticas. Esta lista es considerada el estándar de facto en la industria y es referenciada por frameworks de compliance como PCI DSS, SOC 2 y ISO 27001.

Como desarrollador, conocer el OWASP Top 10 no es opcional: es tu responsabilidad escribir código seguro. La mayoría de brechas de seguridad no son causadas por atacantes sofisticados explotando vulnerabilidades zero-day, sino por errores básicos que los desarrolladores cometen por desconocimiento. Este artículo te ayudará a identificar y prevenir cada una de estas vulnerabilidades en tu código.

1. Broken Access Control (Control de Acceso Roto)

El control de acceso roto es la vulnerabilidad número uno según OWASP. Ocurre cuando los usuarios pueden actuar fuera de sus permisos previstos: acceder a datos de otros usuarios, modificar recursos que no les pertenecen, o elevar sus privilegios a administrador.

Ejemplo: Un usuario modifica la URL de /api/users/123/profile a /api/users/456/profile y accede al perfil de otro usuario porque el servidor no verifica que el usuario autenticado sea el propietario del recurso 123.

Prevención: Implementa verificación de autorización en cada endpoint, no solo en el frontend. Usa el principio de mínimo privilegio: cada usuario solo debería poder acceder a los recursos estrictamente necesarios. Implementa logs de acceso fallidos y alerta sobre patrones sospechosos. Nunca confíes en que el frontend oculte opciones; la seguridad debe estar siempre en el servidor.

2. Cryptographic Failures (Fallos Criptográficos)

Esta categoría incluye cualquier fallo relacionado con la criptografía: contraseñas almacenadas en texto plano, datos sensibles transmitidos sin cifrar, uso de algoritmos débiles (MD5, SHA1 para contraseñas), claves hardcodeadas en el código fuente, o certificados SSL/TLS mal configurados.

Prevención: Usa bcrypt, scrypt o Argon2 para hashear contraseñas (nunca MD5 o SHA). Cifra todos los datos sensibles en tránsito (HTTPS obligatorio) y en reposo. Usa variables de entorno para claves y secretos, nunca los incluyas en el código. Mantén tus dependencias criptográficas actualizadas y usa librerías probadas y auditadas, nunca implementes tu propia criptografía.

3. Injection (Inyección)

Las vulnerabilidades de inyección ocurren cuando datos no confiables se envían a un intérprete como parte de un comando o consulta. Los tipos más comunes son SQL Injection (inyección de código SQL en consultas a bases de datos), Command Injection (ejecución de comandos del sistema operativo), LDAP Injection y NoSQL Injection.

Ejemplo de SQL Injection: Una consulta como SELECT * FROM users WHERE email = '" + email + "' es vulnerable. Si el atacante introduce ' OR '1'='1 como email, la consulta devuelve todos los usuarios de la base de datos.

Prevención: Usa consultas preparadas (parameterized queries) o un ORM que las use internamente. Nunca construyas queries SQL concatenando strings con datos del usuario. Valida y sanitiza todas las entradas del usuario. Usa el principio de mínimo privilegio para las cuentas de base de datos: la cuenta de la aplicación no debería tener permisos de DROP TABLE o acceso a otras bases de datos.

4. Insecure Design (Diseño Inseguro)

El diseño inseguro se refiere a fallos arquitectónicos y de diseño que no se pueden resolver con una implementación correcta. Son problemas fundamentales en cómo se concibió el sistema: falta de rate limiting, ausencia de verificación de propiedad de recursos, flujos de negocio que pueden ser abusados, o trust boundaries mal definidos.

Prevención: Realiza modelado de amenazas (threat modeling) durante la fase de diseño. Identifica los activos críticos, los posibles atacantes y los vectores de ataque. Implementa controles de seguridad desde el diseño, no como parches posteriores. Usa patrones de seguridad establecidos como defense in depth, zero trust y least privilege.

5. Security Misconfiguration (Configuración Incorrecta de Seguridad)

La configuración incorrecta es una de las vulnerabilidades más comunes y fáciles de prevenir. Incluye: servidores con configuraciones por defecto, cuentas de administrador con contraseñas predeterminadas, directorios listados públicamente, headers de seguridad faltantes, mensajes de error que revelan información sensible (stack traces, versiones de software), y servicios innecesarios habilitados.

Prevención: Automatiza la configuración de seguridad con scripts o herramientas como Ansible. Elimina o deshabilita funcionalidades, frameworks y servicios que no necesitas. Implementa headers de seguridad HTTP: Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security. Usa herramientas como Mozilla Observatory para auditar tu configuración.

6. Vulnerable and Outdated Components (Componentes Vulnerables y Desactualizados)

Las aplicaciones modernas dependen de cientos de librerías de terceros. Si una de estas librerías tiene una vulnerabilidad conocida y no la actualizas, tu aplicación es vulnerable. El ejemplo más famoso es Equifax (2017), donde una brecha que expuso datos de 147 millones de personas fue causada por una versión desactualizada de Apache Struts con una vulnerabilidad para la que existía parche desde meses antes.

Prevención: Usa herramientas de análisis de dependencias como npm audit, Snyk, Dependabot o Renovate para detectar y actualizar dependencias vulnerables automáticamente. Configura alertas de seguridad en GitHub/GitLab. Elimina dependencias que no usas. Revisa las dependencias antes de añadirlas: ¿está mantenida? ¿tiene un equipo activo? ¿es popular?

7. Identification and Authentication Failures (Fallos de Identificación y Autenticación)

Esta categoría cubre debilidades en los mecanismos de autenticación y gestión de sesiones: contraseñas débiles sin requisitos mínimos, ausencia de autenticación multifactor (MFA), sesiones que no expiran, tokens que no se invalidan tras logout, credential stuffing (ataques con listas de credenciales filtradas), y almacenamiento inseguro de tokens.

Prevención: Implementa MFA para todas las cuentas, especialmente administradores. Usa rate limiting en endpoints de login para prevenir fuerza bruta. Implementa políticas de contraseñas razonables (mínimo 12 caracteres, sin requisitos arbitrarios de caracteres especiales). Usa sesiones con expiración corta y refresh tokens. Almacena tokens en cookies httpOnly con flag Secure y SameSite=Strict, nunca en localStorage.

8. Software and Data Integrity Failures (Fallos de Integridad de Software y Datos)

Los fallos de integridad ocurren cuando se usan plugins, librerías, módulos o datos de fuentes no verificadas sin validar su integridad. El ataque de cadena de suministro (supply chain attack) más notable fue el de SolarWinds en 2020, donde atacantes comprometieron el software de actualización legítimo para distribuir malware a 18.000 organizaciones.

Prevención: Usa Subresource Integrity (SRI) para scripts cargados desde CDNs. Verifica las firmas de los paquetes npm/pip antes de instalarlos. Usa lockfiles (package-lock.json, yarn.lock) para garantizar versiones exactas de dependencias. Revisa los cambios en dependencias antes de actualizar. Considera usar un registry privado con análisis de seguridad integrado.

9. Security Logging and Monitoring Failures (Fallos de Logging y Monitoreo de Seguridad)

Sin logging y monitoreo adecuados, las brechas de seguridad pueden pasar desapercibidas durante meses. El tiempo medio de detección de una brecha es de más de 200 días. Si no registras intentos de login fallidos, accesos no autorizados, errores de validación de entrada y acciones sensibles, no podrás detectar ni investigar un ataque en curso.

Prevención: Registra todos los eventos de seguridad: logins exitosos y fallidos, cambios de permisos, accesos a datos sensibles, errores de validación. Implementa alertas automáticas para patrones sospechosos (múltiples logins fallidos, accesos desde IPs inusuales). Usa un sistema centralizado de logs como ELK Stack, Datadog o Grafana Loki. Asegúrate de que los logs no contienen datos sensibles (contraseñas, tokens, PII).

10. Server-Side Request Forgery (SSRF)

SSRF ocurre cuando una aplicación web hace peticiones HTTP a URLs proporcionadas por el usuario sin validarlas adecuadamente. Un atacante puede explotar esto para acceder a servicios internos, metadatos de instancias cloud (como los metadatos de AWS EC2 que contienen credenciales temporales), o escanear la red interna.

Ejemplo: Una aplicación que permite al usuario introducir una URL para importar una imagen. El atacante introduce http://169.254.169.254/latest/meta-data/iam/security-credentials/ y obtiene las credenciales IAM del servidor en AWS.

Prevención: Valida y sanitiza todas las URLs proporcionadas por el usuario. Usa allowlists de dominios permitidos. Bloquea peticiones a rangos de IP privados (10.x.x.x, 172.16.x.x, 192.168.x.x, 169.254.x.x). Deshabilita redirecciones HTTP en las peticiones del servidor. Usa un proxy o servicio dedicado para peticiones externas en lugar de hacerlas directamente desde tu servidor de aplicación.

Herramientas para testing de seguridad

SAST (Static Application Security Testing): Herramientas como SonarQube, Semgrep y CodeQL analizan tu código fuente en busca de patrones vulnerables sin ejecutar la aplicación. Intégralas en tu pipeline de CI para detectar vulnerabilidades antes de llegar a producción.

DAST (Dynamic Application Security Testing): Herramientas como OWASP ZAP, Burp Suite y Nikto analizan tu aplicación en ejecución, enviando peticiones maliciosas y verificando respuestas. Son complementarias a SAST y detectan vulnerabilidades que solo se manifiestan en runtime.

SCA (Software Composition Analysis): Herramientas como Snyk, Dependabot y npm audit analizan tus dependencias de terceros en busca de vulnerabilidades conocidas (CVEs). Configúralas para ejecutarse automáticamente y crear PRs con actualizaciones de seguridad.

Secret scanning: Herramientas como GitGuardian, truffleHog y el secret scanning nativo de GitHub detectan credenciales, API keys y tokens accidentalmente commiteados al repositorio. Activa estas herramientas desde el primer commit para prevenir filtraciones.

Conclusión

La seguridad no es un feature que se añade al final del desarrollo; es una mentalidad que debe estar presente en cada línea de código que escribes. El OWASP Top 10 es tu checklist mínimo de seguridad: si puedes prevenir estas diez categorías de vulnerabilidades, tu aplicación será significativamente más segura que la media.

Invierte tiempo en aprender seguridad web de forma continua. Las amenazas evolucionan constantemente y las técnicas de prevención también. Participa en CTFs (Capture The Flag) de seguridad, lee write-ups de vulnerabilidades reales, y practica en entornos controlados como OWASP WebGoat o HackTheBox. La seguridad es una habilidad que se mejora con la práctica constante.