Tema 16

16. Desarrollo seguro, pruebas de seguridad y buenas practicas de mantenimiento

La seguridad de una aplicacion web no se decide solo en produccion. Se construye desde el analisis inicial, se refuerza durante el desarrollo, se valida con pruebas y se sostiene con mantenimiento continuo. Cuando la seguridad se incorpora tarde, suele convertirse en correccion costosa. Cuando se integra desde el ciclo de vida, se vuelve una propiedad mucho mas estable del sistema.

Objetivo Integrar la seguridad en todo el ciclo de vida de la aplicacion
Enfoque Diseño, codificacion, testing y mantenimiento continuo
Resultado Reducir vulnerabilidades antes de que lleguen a produccion

16.1 Introduccion

Muchas vulnerabilidades no aparecen por una sola falla espectacular, sino por decisiones pequenas acumuladas: una validacion ausente, una dependencia desactualizada, una revision superficial, una configuracion insegura o un flujo mal pensado desde el inicio. Por eso, la seguridad real no depende solamente de agregar controles al final del proyecto.

Una aplicacion web segura se diseña, se implementa, se prueba y se mantiene con criterios consistentes. A este enfoque suele llamarselo desarrollo seguro o integracion de seguridad en el ciclo de vida.

16.2 Que significa desarrollo seguro

Desarrollo seguro significa incorporar preocupaciones de seguridad desde las primeras etapas del sistema, no solo cuando aparece un incidente o antes de una auditoria. Implica pensar en amenazas, datos sensibles, superficies de ataque, controles, pruebas y mantenimiento como parte normal del trabajo de ingenieria.

No se trata de frenar desarrollo, sino de evitar que el producto crezca sobre supuestos inseguros que luego resulten caros de corregir.

16.3 Seguridad desde el analisis y el diseño

Las decisiones de diseño condicionan gran parte de la seguridad futura. Si una aplicacion define mal sus trust boundaries, concentra demasiado privilegio, mezcla responsabilidades o expone datos innecesarios, luego el codigo quedara forzado a convivir con una arquitectura debil.

En esta etapa conviene preguntarse:

  • Que datos son sensibles y donde circularan.
  • Que actores interactuaran con el sistema.
  • Que operaciones requieren autenticacion, autorizacion o trazabilidad.
  • Que componentes externos participan y que riesgos agregan.
  • Que abuso funcional podria intentar un atacante.

16.4 Modelado de amenazas

El modelado de amenazas es una forma sistematica de pensar como podria fallar o ser atacada una aplicacion antes de implementarla por completo. No requiere siempre un proceso enorme; incluso una version simple ayuda mucho.

Consiste en identificar activos valiosos, entradas controladas por terceros, limites de confianza, flujos de datos, operaciones sensibles y posibles abusos. Esta practica obliga a mirar la aplicacion como la miraria un atacante o un auditor tecnico.

Pensar amenazas temprano no elimina todos los problemas, pero reduce mucho la probabilidad de que ciertas vulnerabilidades nazcan en el diseño.

16.5 Codificacion segura y estandares internos

Durante la implementacion, la seguridad depende de patrones repetibles. Si cada desarrollador decide a su manera como validar entradas, construir consultas, manejar errores o verificar permisos, el resultado suele ser inconsistente.

Por eso conviene definir estandares internos de codificacion segura: consultas parametrizadas, validacion por allowlist, escape segun contexto, control de acceso centralizado, manejo seguro de secretos, logs estructurados y reglas claras para errores y respuestas.

16.6 Revisiones de codigo con foco en seguridad

La revision de codigo no deberia limitarse a estilo, legibilidad o rendimiento. Tambien debe preguntar si el cambio introduce nueva superficie de ataque, rompe supuestos de autenticacion, expone datos de mas o delega demasiado en el cliente.

Una buena revision de seguridad suele buscar:

  • Entradas no validadas o validadas de forma incompleta.
  • Consultas, comandos o plantillas construidas con datos inseguros.
  • Controles de acceso ausentes o aplicados en el frontend.
  • Errores que filtran informacion interna.
  • Uso riesgoso de librerias, serializacion o archivos.

16.7 Pruebas funcionales y pruebas de seguridad

Las pruebas funcionales responden si la aplicacion hace lo que debe hacer. Las pruebas de seguridad preguntan ademas si puede resistir entradas maliciosas, secuencias imprevistas, abuso automatizado y consumidores hostiles.

Ambos tipos de prueba son necesarios. Una funcion puede cumplir perfectamente el caso de uso esperado y, sin embargo, ser insegura ante parametros alterados, identificadores ajenos o interacciones no previstas por la interfaz.

16.8 Pruebas manuales de seguridad

Las pruebas manuales permiten razonar sobre logica, contexto y abuso de negocio. Son especialmente utiles para revisar autorizacion, flujos multi paso, combinacion de funciones, exposicion de datos, manejo de estados y errores de diseño.

El analisis manual tambien ayuda a descubrir problemas que las herramientas automaticas suelen pasar por alto, como validaciones semanticas debiles o decisiones peligrosas delegadas al cliente.

16.9 Pruebas automaticas y herramientas de apoyo

Las herramientas automaticas son valiosas para escalar controles repetitivos. Entre ellas pueden incluirse analisis estatico, escaneo de dependencias, linters orientados a seguridad, pruebas dinamicas y chequeos dentro del pipeline de integracion continua.

Sin embargo, estas herramientas no entienden por si solas toda la logica del negocio. Deben verse como apoyo al criterio tecnico, no como reemplazo del analisis humano.

16.10 Tipos de pruebas utiles en una aplicacion web

Tipo de prueba Que ayuda a detectar Limite principal
Revision manual Logica, autorizacion, abuso de flujo Requiere experiencia y tiempo
Analisis estatico Patrones inseguros en codigo Puede generar falsos positivos o no ver contexto
Analisis dinamico Problemas observables en ejecucion No cubre toda la logica interna
Escaneo de dependencias Componentes vulnerables conocidos No detecta errores propios de negocio o integracion
Pruebas de penetracion Explotabilidad real en un entorno concreto Suelen ser puntuales, no continuas

16.11 Seguridad en dependencias y cadena de suministro

La mayoria de las aplicaciones modernas dependen de frameworks, paquetes, bibliotecas, contenedores, servicios y componentes de terceros. Cada uno puede introducir vulnerabilidades o riesgos de mantenimiento.

Por eso no basta con revisar solo el codigo propio. Tambien hay que inventariar dependencias, actualizar con criterio, retirar componentes obsoletos, verificar procedencia y evitar agregar librerias innecesarias para resolver problemas pequenos.

16.12 Gestion de secretos y configuracion durante desarrollo

Uno de los errores mas comunes es tratar secretos, tokens, credenciales de prueba o configuraciones sensibles como si fueran datos cualquiera. Aparecen entonces claves en repositorios, archivos compartidos, scripts de despliegue o variables expuestas accidentalmente.

El desarrollo seguro requiere separar secretos del codigo, usar mecanismos adecuados de almacenamiento y rotacion, y revisar que entornos de desarrollo, prueba y produccion no mezclen credenciales ni privilegios de forma riesgosa.

16.13 Integracion de seguridad en CI/CD

Cuando una aplicacion evoluciona rapido, conviene que ciertos controles corran de forma automatica en el pipeline. Esto puede incluir chequeos de dependencias, analisis estatico, pruebas de seguridad basicas, validacion de configuraciones y verificacion de politicas antes del despliegue.

La ventaja es detectar problemas temprano, cuando corregirlos aun es barato. La desventaja de no hacerlo es que el sistema aprende a mover cambios inseguros con demasiada facilidad.

16.14 Hardening posterior al desarrollo

Escribir codigo correcto no reemplaza el endurecimiento operativo. Una aplicacion bien desarrollada aun puede quedar expuesta si se despliega con cabeceras ausentes, permisos excesivos, configuracion por defecto, logs inseguros o servicios auxiliares abiertos innecesariamente.

Por eso el cierre de un cambio deberia contemplar no solo funcionalidad, sino tambien configuracion efectiva, observabilidad, secretos, permisos, politicas de despliegue y consistencia entre ambientes.

16.15 Mantenimiento: la seguridad cambia con el tiempo

La seguridad no es una foto. El contexto cambia: aparecen nuevas vulnerabilidades, cambian las dependencias, evolucionan navegadores, se agregan endpoints, se modifican flujos y se descubren tecnicas de abuso que antes no estaban en el radar.

Por eso una aplicacion necesita mantenimiento continuo. Revisar configuraciones, actualizar componentes, retirar funciones viejas, revalidar permisos y adaptar controles es parte del trabajo normal si se pretende conservar un nivel razonable de seguridad.

16.16 Deuda tecnica y deuda de seguridad

Cuando una decision insegura se acepta como temporal y nunca se corrige, nace deuda de seguridad. Esa deuda puede tomar la forma de validaciones pendientes, dependencias congeladas, endpoints heredados, permisos excesivos o parches rapidos que nadie revisita.

Si se acumula, la aplicacion se vuelve cada vez mas fragil. Gestionar deuda de seguridad significa identificarla, priorizarla y no permitir que quede oculta detras de urgencias funcionales permanentes.

16.17 Documentacion y transferencia de conocimiento

Los controles sirven mucho menos si solo viven en la cabeza de una persona. Documentar decisiones relevantes, flujos de autenticacion, supuestos de autorizacion, dependencias criticas, procedimientos de rotacion y criterios de despliegue ayuda a sostener la seguridad cuando cambia el equipo o el sistema crece.

La documentacion util no es burocracia: es una forma de evitar que el conocimiento de seguridad se pierda o se aplique de manera inconsistente.

16.18 Buenas practicas sostenibles de mantenimiento

  • Actualizar dependencias con regularidad y criterio.
  • Revisar endpoints viejos, funciones poco usadas y configuraciones heredadas.
  • Monitorear vulnerabilidades publicadas que afecten al stack usado.
  • Rotar secretos y revisar privilegios de servicios y cuentas tecnicas.
  • Repetir pruebas de seguridad despues de cambios relevantes.
  • Tratar findings de seguridad como trabajo de ingenieria real, no como notas marginales.

16.19 Ejemplo conceptual integrado

Imaginemos una aplicacion que agrega una nueva API de facturacion. El cambio funciona bien en pruebas funcionales, pero nadie revisa autorizacion por recurso, una dependencia de serializacion queda desactualizada y el pipeline no escanea componentes vulnerables. Meses despues aparece una falla publicada en esa libreria y un cliente autenticado descubre que puede consultar facturas ajenas alterando un identificador.

Este escenario no nace de un unico error, sino de una cadena: diseño incompleto, revision insuficiente, testing limitado y mantenimiento pobre. Justamente por eso el desarrollo seguro debe verse como proceso continuo y no como una etapa aislada.

16.20 Que debes recordar de este tema

  • La seguridad debe incorporarse desde el diseño, no agregarse solo al final.
  • Revisiones de codigo, pruebas manuales y herramientas automaticas cumplen roles complementarios.
  • Las dependencias y configuraciones tambien forman parte de la superficie de ataque.
  • CI/CD puede ayudar a detectar problemas temprano, pero no reemplaza criterio tecnico.
  • El mantenimiento continuo es indispensable para sostener la seguridad en el tiempo.

16.21 Cierre del curso

La seguridad en aplicaciones web no se resuelve con una sola herramienta, una lista de cabeceras o una auditoria puntual. Requiere comprender amenazas, proteger identidad y datos, limitar superficie, observar el sistema y desarrollar con disciplina tecnica. A lo largo del curso vimos que casi todas las fallas importantes surgen cuando el sistema confia demasiado, valida poco, expone de mas o deja de revisarse con el tiempo.

El objetivo final no es construir aplicaciones perfectas, sino aplicaciones razonablemente seguras, entendibles, mantenibles y capaces de resistir mejor errores, abuso y cambio constante. Ese es el verdadero sentido de trabajar seguridad como parte de la ingenieria.