Ciclo de Vida Seguro del Desarrollo de Software (SSDLC)
Introducción
El desarrollo de software moderno no puede prescindir de la seguridad. La complejidad de las arquitecturas actuales, la proliferación de amenazas y la creciente presión normativa exigen un enfoque estructurado y sistemático para proteger aplicaciones desde su concepción hasta su mantenimiento.
El Ciclo de Vida Seguro del Desarrollo de Software (SSDLC) propone precisamente eso: incorporar prácticas de seguridad en cada fase del desarrollo, desde la recolección de requisitos hasta el mantenimiento postproducción. Adoptar un SSDLC no solo reduce la superficie de ataque y el riesgo de vulnerabilidades explotables, sino que también disminuye los costos de remediación, mejora la calidad del producto y fortalece la confianza del usuario.
Este artículo parte de la serie “Código Seguro” ofrece una guía práctica para implementar un SSDLC moderno, alineado con marcos como OWASP SAMM, NIST, ISO 27034 y DevSecOps.
Planificación y Análisis de Requisitos
Objetivo
Identificar desde el inicio los activos críticos, riesgos asociados y requisitos de seguridad que deben estar presentes en el sistema.
Buenas prácticas
- Entrevistar stakeholders con enfoque en seguridad.
- Identificar normativas aplicables (PCI-DSS, HIPAA, GDPR, etc.).
- Establecer requisitos no funcionales explícitos (confidencialidad, integridad, disponibilidad).
- Incluir criterios de aceptación relacionados con la seguridad.
- Categorizar datos según su sensibilidad (p. ej., personales, financieros, técnicos).
Errores comunes
- Tratar la seguridad como un requerimiento “extra”.
- No prever riesgos asociados al dominio (por ejemplo, fraude financiero en fintech).
- No consultar al equipo de seguridad desde el inicio.
Ejemplo práctico
Historia de usuario segura:
"Como usuario, quiero que la plataforma almacene mi contraseña de forma segura para que nadie pueda acceder a ella incluso si se compromete la base de datos."
Criterios de aceptación:
- Hash con `bcrypt` + salt aleatorio.
- Validación de complejidad mínima.
- Proceso de recuperación por MFA y correo verificado.
Diseño Seguro del Sistema
Objetivo
Proponer una arquitectura robusta, documentada y resiliente frente a amenazas previsibles, evitando patrones inseguros desde el diseño.
Subtemas clave
- Modelado de amenazas (STRIDE, LINDDUN, PASTA).
- Zonificación (DMZ, backend, frontend, third-party).
- Diagramas DFD, arquitectura en capas, zero trust.
- Definición temprana de controles: cifrado, autenticación, gestión de sesiones, etc.
Buenas prácticas
- Usar herramientas de modelado como OWASP Threat Dragon o Microsoft Threat Modeling Tool.
- Diseñar APIs con principio de mínimo privilegio.
- Incluir métricas de seguridad como parte del diseño técnico.
Ejemplo real
Supongamos que diseñás un sistema de pagos: el modelado de amenazas debería identificar riesgos como:
- MitM si no hay TLS.
- Inyección en parámetros si no hay validación.
- Fraude si no hay controles de autenticación reforzada.
Desarrollo Seguro
Objetivo
Garantizar que el código fuente cumpla estándares de seguridad, evitando errores comunes que derivan en vulnerabilidades.
Recomendaciones generales
- Validar y sanear todas las entradas (input validation).
- Aplicar el principio de menor privilegio (least privilege).
- No usar funciones inseguras (
eval()
,exec()
, etc.). - Proteger contra inyecciones SQL, XSS, LFI, CSRF, etc.
- Usar librerías mantenidas y actualizadas.
- Prohibir credenciales hardcodeadas y usar secretos seguros.
Fragmento de código inseguro
# Peligroso: SQL Injection
cursor.execute("SELECT * FROM users WHERE username = '" + username + "'")
Fragmento de código seguro
# Uso de parámetros preparados
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
Herramientas útiles
- Linters como
eslint-plugin-security
obandit
. - Reglas de análisis SAST (SonarQube, Semgrep, Checkmarx).
- Hooks en Git para bloquear commits con secretos (como
pre-commit
ygit-secrets
).
Pruebas de Seguridad (Testing)
Objetivo
Detectar vulnerabilidades antes de llegar a producción mediante pruebas estructuradas.
Tipos de pruebas
Tipo | Descripción | Herramientas |
---|---|---|
SAST | Analiza código fuente estático | Semgrep, SonarQube, CodeQL |
DAST | Prueba la app en ejecución | OWASP ZAP, Burp Suite |
SCA | Analiza dependencias | Snyk, Trivy, OWASP Dependency-Check |
IAST | Prueba instrumentada | Contrast Security |
RASP | Protección en tiempo real | Sqreen, AppSensor |
Buenas prácticas
- Incluir pruebas de fuzzing y abuso lógico.
- Simular ataques de fuerza bruta, enumeración de usuarios, bypass de roles.
- Automatizar pruebas en CI/CD, pero revisar manualmente resultados críticos.
Ejemplo: reporte falso en login
# Respuesta insegura
if not user_exists(username):
return "Usuario inexistente"
Esto permite ataques de enumeración. Lo correcto es:
return "Si las credenciales son válidas, accederá al sistema"
Integración y Despliegue Continuos (CI/CD Seguros)
Objetivo
Garantizar que la seguridad forme parte de los pipelines automáticos y no se pierda en el camino al entorno productivo.
Buenas prácticas
- Escaneo automático de código, dependencias y secretos.
- Validación de firmas de artefactos.
- Definición de políticas de despliegue basadas en riesgo.
- Despliegue canary o blue/green para validar sin afectar a todos los usuarios.
Fragmento de ejemplo (GitHub Actions)
name: CI Security Pipeline
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Análisis SAST con Semgrep
run: semgrep --config "p/owasp-top-ten" .
- name: Análisis de dependencias
uses: aquasecurity/trivy-action@master
Mantenimiento, Monitoreo y Respuesta a Incidentes
Objetivo
Proteger la aplicación una vez desplegada, detectando y respondiendo a comportamientos anómalos.
Buenas prácticas
- Implementar observabilidad (trazabilidad, métricas, logs).
- Usar herramientas SIEM o alertas personalizadas.
- Aplicar parches de seguridad de forma continua.
- Revisar sesiones activas y dispositivos autenticados.
- Tener un plan de respuesta a incidentes formalizado.
Ejemplo: detección de acceso sospechoso
if login_ip != known_ip or device != known_device:
send_alert(user_email, "Nuevo acceso detectado desde ubicación inusual.")
📋 Checklist SSDLC (Ciclo Completo)
- Requisitos de seguridad definidos en la planificación.
- Modelado de amenazas durante el diseño.
- Principios de diseño seguro aplicados.
- Revisión de código estática automatizada (SAST).
- Escaneo de dependencias (SCA).
- Pruebas dinámicas (DAST).
- Escaneo en pipelines CI/CD.
- Gestión segura de secretos.
- Pruebas manuales de lógica de negocio.
- Plan de respuesta a incidentes.
- Monitoreo activo de logs, alertas y anomalías.
- Parcheo y mantenimiento regular de librerías.
📚 Referencias técnicas
📖 OWASP
📌 NIST
- SP 800-64: Security Considerations in the System Development Life Cycle
- NIST SSDF (Secure Software Development Framework)
🔧 Herramientas
Si querés sumar SSDLC a tu flujo de trabajo, lo primero es cambiar el mindset: la seguridad no es una etapa, es una cultura.