OWASP Top 10: Explicado con Mitigaciones
Guía orientada a desarrolladores sobre los 10 riesgos de seguridad más críticos de OWASP: cómo funciona cada vulnerabilidad, ejemplos del mundo real y mitigaciones prácticas.
Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.
Overview
El OWASP Top 10 es un documento de concienciación estándar para desarrolladores y seguridad de aplicaciones web. Representa un consenso amplio sobre los riesgos de seguridad más críticos para aplicaciones web. Entender estos riesgos, y más importante aún cómo prevenirlos, es una habilidad base para todo desarrollador que envíe código a producción.
When to Use
-
For alternatives, see Content Security Policy: CSP Headers, Nonces, Hashes.
-
Construyes o mantienes aplicaciones web
-
Necesitas comunicar riesgos de seguridad a stakeholders
-
Preparas auditorías de seguridad o pruebas de penetración
-
Quieres establecer estándares de codificación segura
A01: Control de Acceso Roto
Riesgo: Los usuarios pueden acceder a recursos o realizar acciones fuera de sus permisos previstos.
Ejemplo: Un atacante cambia la URL de /account/123 a /account/124 y ve los datos de otro usuario.
Mitigación:
- Denegar por defecto; validar en el servidor en cada solicitud
- Usar un mecanismo único y reutilizable de control de acceso
- Implementar políticas CORS adecuadas
- Limitar la tasa de solicitudes a endpoints de API para prevenir abuso automatizado
# Verificación de autorización en el servidor
def get_account(account_id: str, user: User):
account = db.get_account(account_id)
if account.owner_id != user.id and not user.is_admin:
raise Forbidden("Acceso denegado")
return account
A02: Fallas Criptográficas
Riesgo: Los datos sensibles se exponen a través de encriptación débil o ausente.
Ejemplo: Contraseñas almacenadas en texto plano, o números de tarjetas transmitidos por HTTP.
Mitigación:
- Encriptar datos en reposo (AES-256) y en tránsito (TLS 1.3)
- Usar hashing fuerte de contraseñas: Argon2id, scrypt o bcrypt
- Nunca almacenar datos sensibles que no necesites (cumplimiento PCI DSS)
- Usar generadores de números aleatorios seguros para tokens e IDs
import bcrypt
# Hashear una contraseña
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
# Verificar
if bcrypt.checkpw(password.encode(), hashed):
# Autenticado
A03: Inyección
Riesgo: Datos no confiables se envían a un intérprete como parte de un comando o consulta.
Ejemplo: Inyección SQL a través de entrada de usuario no sanitizada en un campo de búsqueda.
Mitigación:
- Usar consultas parametrizadas (prepared statements)
- Usar ORMs que escapan consultas automáticamente
- Validar y sanitizar toda la entrada del usuario
- Usar LIMIT en consultas SQL para minimizar el daño de inyecciones
# Seguro: consulta parametrizada
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
# Inseguro: formato de string
cursor.execute(f"SELECT * FROM users WHERE email = '{email}'")
A04: Diseño Inseguro
Riesgo: Fallas en el diseño de la aplicación que no pueden ser corregidas solo con implementación perfecta.
Ejemplo: Un flujo de restablecimiento de contraseña que envía un token predecible en la URL.
Mitigación:
- Establecer patrones de diseño seguro y modelado de amenazas
- Usar arquitecturas de referencia con seguridad integrada
- Separar dominios en contextos acotados con autenticación independiente
- Implementar pruebas unitarias e integrales de controles de seguridad
A05: Configuración de Seguridad Incorrecta
Riesgo: Configuraciones por defecto, configuraciones incompletas o demasiado permisivas.
Ejemplo: Credenciales de administrador por defecto, almacenamiento cloud expuesto o capacidades innecesarias habilitadas.
Mitigación:
- Endurecer todos los ambientes (dev, staging, prod) por igual
- Eliminar capacidades, dependencias y documentación no utilizadas
- Segmentar la arquitectura de la aplicación (containers, serverless)
- Automatizar la validación de configuración en pipelines CI/CD
A06: Componentes Vulnerables y Desactualizados
Riesgo: Usar componentes con vulnerabilidades conocidas.
Ejemplo: Ejecutar Log4j 2.14.1 después de la divulgación de CVE-2021-44228.
Mitigación:
- Mantener un inventario de software (SBOM)
- Usar escáners de dependencias (Snyk, OWASP Dependency-Check, npm audit)
- Suscribirse a avisos de seguridad para tu stack
- Tener un SLA de parches (crítico: 24h, alto: 7 días)
A07: Fallas de Identificación y Autenticación
Riesgo: Debilidades de autenticación permiten credential stuffing, fuerza bruta o secuestro de sesiones.
Ejemplo: Sin límite de tasa en login, sesiones que nunca expiran o políticas de contraseña débiles.
Mitigación:
- Implementar autenticación multifactor (MFA)
- Usar gestión segura de sesiones (cookies httpOnly, secure, SameSite)
- Hacer cumplir políticas de contraseñas fuertes o autenticación sin contraseña
- Detectar y bloquear intentos de credential stuffing
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict; Max-Age=3600
A08: Fallas de Integridad de Software y Datos
Riesgo: Aplicaciones que dependen de plugins, librerías o módulos de fuentes no confiables.
Ejemplo: Un pipeline CI/CD que obtiene dependencias sin verificar firmas.
Mitigación:
- Verificar firmas digitales de paquetes y actualizaciones
- Usar repositorios privados con controles de acceso estrictos
- Asegurar que los pipelines CI/CD tengan controles de acceso fuertes y logging de auditoría
- No actualizar automáticamente dependencias de producción
A09: Fallas de Logging y Monitoreo de Seguridad
Riesgo: Logging insuficiente previene la detección de brechas y ralentiza la respuesta a incidentes.
Ejemplo: Un ataque de exfiltración de datos que pasa desapercibido durante meses porque no se recolectaban logs.
Mitigación:
- Registrar todas las fallas de autenticación, control de acceso y validación de entrada
- Asegurar que los logs sean resistentes a alteraciones y almacenados centralmente
- Implementar alertas en tiempo real para patrones sospechosos
- Practicar simulacros de respuesta a incidentes con tus logs
A10: Server-Side Request Forgery (SSRF)
Riesgo: Un atacante fuerza al servidor a hacer solicitudes a recursos internos o restringidos.
Ejemplo: Un buscador de URLs que sigue redirecciones a http://169.254.169.254/latest/meta-data/ en AWS.
Mitigación:
- Validar y sanitizar todas las URLs (esquema, host, puerto)
- Usar listas de permitidos para solicitudes salientes
- Desactivar el seguimiento de redirecciones o validar el destino final
- Ejecutar servicios de obtención en segmentos de red aislados
Tabla Resumen
| Rango | Riesgo | Mitigación Clave |
|---|---|---|
| A01 | Control de Acceso Roto | Verificaciones de autorización en el servidor |
| A02 | Fallas Criptográficas | Encriptar datos en reposo y en tránsito |
| A03 | Inyección | Consultas parametrizadas y validación de entrada |
| A04 | Diseño Inseguro | Modelado de amenazas y patrones seguros |
| A05 | Configuración Incorrecta | Endurecer todos los ambientes por igual |
| A06 | Componentes Vulnerables | Escaneo de dependencias y SLAs de parches |
| A07 | Fallas de Autenticación | MFA, sesiones seguras, límite de tasa |
| A08 | Fallas de Integridad | Verificación de firmas y seguridad de cadena de suministro |
| A09 | Fallas de Logging | Logging centralizado resistente a alteraciones |
| A10 | SSRF | Validación de URLs y segmentación de red |
Errores Comunes
- Pensar que el framework lo maneja todo. Los frameworks ayudan, pero aún necesitas configurarlos correctamente
- Solo probar XSS y SQLi. Las aplicaciones modernas enfrentan riesgos de cadena de suministro, lógica de negocio y SSRF
- Tratar la seguridad como algo posterior. Construye seguridad en el diseño, no como una lista de verificación pre-lanzamiento
- Ignorar variantes móviles y de API. OWASP tiene listas separadas para seguridad móvil y de APIs
Troubleshooting
- Authentication bypass in tests: ensure test users cannot reach production endpoints. Use separate credentials and environments for CI.
- False positives in scanning tools: tune rules against the risk profile. Distinguish between reachable vulnerabilities and theoretical issues.
- Secrets appear in logs: configure log filters to redact tokens, passwords, and keys. Audit log sinks for sensitive patterns.
- CSP breaks legitimate functionality: use report-only mode first, then enforce. Iterate on allowed sources based on real violations.
- Incident response stalls: run tabletop exercises. Document escalation paths, evidence collection steps, and communication templates in advance.
FAQ
¿Con qué frecuencia actualiza OWASP el Top 10?
Aproximadamente cada 3-4 años. La versión actual es de 2021. Consulta owasp.org para actualizaciones.
¿Es OWASP Top 10 suficiente para cumplimiento?
Es un excelente punto de partida pero no exhaustivo. Considera OWASP ASVS (Application Security Verification Standard) para requisitos exhaustivos.
¿Cómo pruebo estas vulnerabilidades?
Usa escáners automatizados (OWASP ZAP, Burp Suite) como línea base, luego realiza pruebas de penetración manuales y revisión de código.
Temas Avanzados
Escenario: Mitigacion OWASP Top 10 en API REST
Sistema: API REST Node.js + PostgreSQL, 50 endpoints
Objetivo: Mitigar las 10 vulnerabilidades OWASP
A01: Broken Access Control
| Vulnerabilidad | Mitigacion | Implementacion |
|---------------|------------|----------------|
| IDOR en /api/users/:id | Verificar ownership | JWT + scope check |
| Admin sin auth | RBAC estricto | middleware role("admin") |
| API sin rate limit | Rate limiting | express-rate-limit 100/min |
A02: Cryptographic Failures
| Vulnerabilidad | Mitigacion | Implementacion |
|---------------|------------|----------------|
| Password en MD5 | bcrypt + salt rounds 12 | bcrypt.hash(pw, 12) |
| HTTP sin TLS | TLS 1.3 obligatorio | redirect HTTP -> HTTPS |
| JWT con HS256 | RS256 + rotacion de claves | jwt.sign(..., RS256) |
| DB sin cifrar | AES-256 at rest | AWS RDS encryption |
A03: Injection
| Vulnerabilidad | Mitigacion | Implementacion |
|---------------|------------|----------------|
| SQL injection | Queries parametrizadas | pool.query(..., [params]) |
| NoSQL injection | Schema validation | Zod safeParse |
| Command injection | No eval/exec | child_process con args array |
| LDAP injection | Input sanitization | escapeLDAP filter |
A04: Insecure Design
| Vulnerabilidad | Mitigacion | Implementacion |
|---------------|------------|----------------|
| Sin threat modeling | STRIDE por feature | Threat model doc |
| Sin rate limit en auth | Rate limit + lockout | 5 intentos -> lock 15min |
| Sin audit log | Append-only log | Audit table + hash chain |
A05: Security Misconfiguration
| Vulnerabilidad | Mitigacion | Implementacion |
|---------------|------------|----------------|
| Headers ausentes | helmet() | X-Frame-Options, CSP, HSTS |
| CORS abierto | Origin estricto | cors({ origin: [...] }) |
| Debug en prod | NODE_ENV=production | app.set("env", "production") |
| Errores con stack | Mensajes genericos | error handler middleware |
A06: Vulnerable Components
| Vulnerabilidad | Mitigacion | Implementacion |
|---------------|------------|----------------|
| Deps desactualizadas | npm audit en CI | npm audit --audit-level=high |
| CVE sin parchear | Renovar semanalmente | Dependabot + Snyk |
| Licencias incompatibles | License check | license-checker en CI |
A07: Auth Failures
| Vulnerabilidad | Mitigacion | Implementacion |
|---------------|------------|----------------|
| Password debil | Min 12 chars + complexity | Zod password schema |
| Sin MFA | TOTP + backup codes | speakeasy + qrcode |
| Session sin expiracion | JWT 15min + refresh | Rotacion de refresh token |
| Brute force | Rate limit + lockout | 5 intentos -> lock 15min |
A08: Data Integrity Failures
| Vulnerabilidad | Mitigacion | Implementacion |
|---------------|------------|----------------|
| JWT sin verificacion | Verify signature + expiry | jwt.verify(token, key) |
| Deserializacion insegura | Schema validation | Zod safeParse |
| CI/CD sin firma | Firmar artifacts | Cosign + Sigstore |
A09: Logging Failures
| Vulnerabilidad | Mitigacion | Implementacion |
|---------------|------------|----------------|
| Sin audit log | Log eventos criticos | winston + audit table |
| Logs sin alerta | SIEM + alertas | ELK + alerting rules |
| Logs con PII | Masking de datos | redact(email, phone) |
A10: SSRF
| Vulnerabilidad | Mitigacion | Implementacion |
|---------------|------------|----------------|
| Fetch de URL usuario | Allowlist de dominios | validateURL(url) |
| Internal metadata | Bloquear 169.254.169.254 | Network policy |
| Redirect SSRF | No seguir redirects | fetch(url, { redirect: "manual" }) |
Lecciones:
- OWASP Top 10 es el minimo, no el objetivo
- Broken Access Control es #1: verifica ownership en cada request
- Queries parametrizadas eliminan SQL injection
- helmet() + CORS estricto en cada API
- npm audit + Dependabot en CI para deps vulnerables
- Audit log inmutable para deteccion y respuesta
Como integro OWASP ZAP en CI/CD?
Usa la imagen Docker de ZAP en tu pipeline: docker run -t owasp/zap2docker-stable zap-baseline.py -t https://staging.example.com. Configura el baseline scan en PRs y el full scan en merges a main. Guarda el reporte como artifact. Falla el pipeline si hay alertas HIGH o CRITICAL. Para APIs, usa zap-api-scan con un OpenAPI spec.
Recursos Relacionados
Prácticas de Codificación Segura — Por Lenguaje y Patrón
Guía práctica de prácticas de codificación segura en varios lenguajes: validación de entrada, seguridad de memoria, autenticación y patrones defensivos para Python, Java, JavaScript y Go.
GuideModelado de Amenazas
Guía paso a paso de modelado de amenazas: STRIDE, árboles de ataque, diagramas de flujo de datos e integración de revisión de diseño de seguridad en tu proceso de desarrollo.
GuideBases de Criptografía — Encriptación, Hashing y Firmas
Guía de criptografía para desarrolladores: encriptación simétrica y asimétrica, hashing, firmas digitales y gestión de claves con ejemplos de código prácticos.