🛡️ ¿Cómo integrar el análisis de vulnerabilidades, las pruebas automatizadas y el despliegue continuo en una aplicación web?

En este artículo comparto mi experiencia desarrollando EstadoSeguro, una aplicación web construida con Python y Flask que integra pruebas con Pytest, análisis de seguridad mediante Nuclei, automatización con GitHub Actions y publicación en la nube utilizando Render.

🚀 1. Introducción

La seguridad informática representa uno de los principales desafíos del desarrollo de software. Actualmente, no basta con construir aplicaciones que funcionen correctamente; también es necesario incorporar mecanismos que permitan identificar posibles vulnerabilidades y problemas de configuración durante su desarrollo.

En este contexto, el enfoque DevSecOps (Development, Security and Operations) propone integrar prácticas de seguridad en las distintas etapas del ciclo de vida del software, mediante herramientas que permiten automatizar pruebas y realizar verificaciones de manera continua.

Como parte del curso de Calidad de Software, desarrollé EstadoSeguro, una aplicación web orientada a la gestión visual y consulta de incidencias de servicios. El propósito principal fue demostrar cómo integrar herramientas de análisis de seguridad dentro de un proceso automatizado de desarrollo y despliegue.

Para ello, se utilizaron tecnologías de código abierto como Python, Flask, Pytest y Nuclei, junto con plataformas como GitHub Actions y Render.

El proyecto permite comprobar que es posible aplicar conceptos de DevSecOps en aplicaciones de pequeña escala, utilizando una infraestructura accesible y manteniendo evidencia verificable de los resultados.

📊 Resumen del proyecto

Componente Implementación
Aplicación EstadoSeguro
Lenguaje Python 3.12
Framework web Flask
Pruebas automatizadas 12 aprobadas
Herramienta de seguridad Nuclei v3.11.1
Integración continua GitHub Actions
Plataforma cloud Render
Despliegue Servicio web gratuito
Estado ✅ Aplicación publicada

🔗 Enlaces del proyecto

💻 Repositorio público: EstadoSeguro en GitHub

🌐 Aplicación desplegada: EstadoSeguro en Render

⚙️ Integración continua: Ejecución satisfactoria de GitHub Actions

🎯 2. Objetivos y tecnologías utilizadas

Objetivo general

Implementar un proceso automatizado de pruebas y análisis de seguridad sobre una aplicación web, integrando Nuclei, GitHub Actions y Render para fortalecer las prácticas de calidad y seguridad del software.

Objetivos específicos

  • Desarrollar una aplicación web funcional mediante Python y Flask.
  • Implementar pruebas automatizadas con Pytest para validar su comportamiento.
  • Diseñar plantillas personalizadas de Nuclei para realizar comprobaciones HTTP.
  • Integrar el análisis de seguridad dentro de GitHub Actions.
  • Publicar la aplicación en Render mediante un despliegue configurado desde GitHub.
  • Documentar los resultados obtenidos, diferenciando las verificaciones informativas de los posibles hallazgos de seguridad.

🧰 Herramientas utilizadas

Tecnología Función
Python y Flask Desarrollo del backend y API REST
HTML, CSS y Jinja Implementación de la interfaz web
Pytest Validación de funcionalidades mediante pruebas
Nuclei Comprobaciones de seguridad HTTP
GitHub Control de versiones y repositorio público
GitHub Actions Automatización de pruebas y escaneos
Render Publicación de la aplicación en la nube
Gunicorn Ejecución del servidor de producción

¿Por qué se seleccionó Nuclei?

Nuclei es una herramienta de análisis de seguridad de código abierto desarrollada por ProjectDiscovery. Su funcionamiento se basa en plantillas YAML que permiten definir solicitudes y condiciones específicas para identificar determinados comportamientos o problemas de configuración.

Una de sus principales ventajas es la capacidad de integrarse con procesos de integración continua, permitiendo ejecutar comprobaciones repetibles después de realizar cambios en una aplicación.

Además, Nuclei aparece dentro del catálogo comunitario de herramientas de escaneo de vulnerabilidades de OWASP. Es importante precisar que la inclusión en este catálogo no constituye una certificación o respaldo oficial de la herramienta.

Para EstadoSeguro se decidió utilizar dos plantillas HTTP personalizadas, manteniendo un alcance controlado y evitando realizar análisis indiscriminados sobre servicios externos.

💻 3. Desarrollo de la aplicación EstadoSeguro

EstadoSeguro es una aplicación web desarrollada con Flask, diseñada para presentar información de incidencias relacionadas con distintos servicios.

La interfaz está construida en español utilizando HTML, CSS y plantillas Jinja. Su diseño responsive permite acceder al sistema desde diferentes tamaños de pantalla.

Para facilitar el desarrollo, la aplicación utiliza datos locales de demostración, evitando la necesidad de configurar una base de datos externa.

Funcionalidades implementadas

Panel principal: presenta información general sobre servicios e incidencias disponibles.

Búsqueda y filtrado: permite localizar registros mediante palabras clave y seleccionar incidencias de acuerdo con su estado.

Vista detallada: proporciona información específica de cada incidencia.

API REST: permite consultar la información mediante solicitudes HTTP y respuestas JSON.

Health check: proporciona una ruta que permite comprobar si la aplicación responde correctamente.

🌐 Endpoints principales

Método Endpoint Funcionalidad
GET / Panel principal
GET /incidencias/<id> Detalle de una incidencia
GET /api/incidencias Consulta JSON de incidencias
GET /api/incidencias/<id> Consulta individual
GET /health Verificación de disponibilidad

Verificación del servicio

El endpoint /health constituye un componente importante porque permite verificar la disponibilidad de EstadoSeguro antes de ejecutar determinadas tareas automatizadas.

Durante la comprobación de la aplicación publicada se obtuvo una respuesta HTTP 200 con el siguiente contenido:

{ "servicio": "EstadoSeguro", "status": "ok" } 

Esta respuesta indica que el servidor atendió correctamente la solicitud durante la verificación.

El endpoint también es utilizado por GitHub Actions para comprobar que la instancia local esté disponible antes de ejecutar Nuclei y por Render para supervisar la disponibilidad del servicio.

🔒 Controles de seguridad implementados

Además de las funcionalidades principales, la aplicación incorpora determinadas medidas de protección.

Entre ellas destacan la validación de parámetros de entrada, el manejo controlado de errores, la configuración mediante variables de entorno y la incorporación de cabeceras HTTP de seguridad.

El parámetro de búsqueda q se encuentra limitado a 100 caracteres, mientras que los valores del filtro estado se verifican mediante una lista permitida.

También se implementaron las siguientes cabeceras:

  • Content-Security-Policy
  • X-Content-Type-Options
  • X-Frame-Options
  • Referrer-Policy
  • Permissions-Policy

Estas cabeceras permiten establecer restricciones sobre el tratamiento del contenido y determinadas capacidades del navegador.

Adicionalmente, el modo debug está desactivado por defecto y la clave SECRET_KEY se obtiene mediante variables de entorno.

Estas medidas mejoran la configuración de la aplicación, aunque no sustituyen una evaluación integral de seguridad.

🧪 4. Pruebas automatizadas con Pytest

Antes de implementar el análisis de seguridad con Nuclei, se desarrolló una suite de pruebas automatizadas utilizando Pytest.

El objetivo fue comprobar que las principales funcionalidades de EstadoSeguro respondieran correctamente ante distintos escenarios.

Las pruebas implementadas evalúan el acceso a la página principal, las búsquedas, los filtros, la validación de parámetros, el escape de contenido HTML, las vistas de detalle, las respuestas de la API REST y determinadas cabeceras de seguridad.

⚙️ Ejecución de pruebas

Desde el directorio del proyecto se utiliza el siguiente comando:

python -m pytest -v 

La opción -v permite mostrar información detallada de los casos ejecutados.

✅ Resultados obtenidos

Indicador Resultado
Total de pruebas 12
Pruebas aprobadas 12
Pruebas fallidas 0
Pruebas omitidas 0
Estado ✅ Satisfactorio

Las 12 pruebas se ejecutaron satisfactoriamente tanto de manera local como dentro del proceso automatizado de GitHub Actions.

Estos resultados proporcionaron una base funcional para continuar con las comprobaciones de seguridad.

Importancia de las pruebas

Automatizar las pruebas permite identificar problemas en los escenarios evaluados y ejecutar las mismas verificaciones después de realizar modificaciones en el repositorio.

Además, la integración con GitHub Actions facilita conservar registros asociados a cada ejecución.

Sin embargo, aprobar todas las pruebas no significa que la aplicación esté libre de defectos. Los resultados únicamente demuestran que los casos implementados cumplieron las condiciones esperadas.

🛡️ 5. Análisis de vulnerabilidades mediante Nuclei

La etapa principal del proyecto consistió en integrar Nuclei dentro del proceso de integración continua.

Esta herramienta permite definir plantillas YAML que contienen solicitudes HTTP y condiciones de evaluación.

Para EstadoSeguro se desarrollaron dos plantillas personalizadas, almacenadas en el directorio:

.nuclei/templates/

🔍 Primera plantilla: comprobación de disponibilidad

Archivo: estadoseguro-health.yaml

Esta plantilla realiza una solicitud HTTP GET al endpoint /health.

Su objetivo es comprobar que el servidor responda con código HTTP 200 y que el cuerpo de la respuesta contenga el estado esperado.

Cuando se cumplen estas condiciones, Nuclei registra una coincidencia informativa con severidad info.

Este resultado confirma que se cumplen las condiciones de la comprobación de disponibilidad.

Es importante aclarar que una coincidencia informativa de disponibilidad no constituye una vulnerabilidad.

🔐 Segunda plantilla: cabeceras HTTP de seguridad

Archivo: missing-security-headers.yaml

La segunda plantilla está orientada a comprobar la presencia de tres cabeceras HTTP:

Cabecera evaluada Propósito
Content-Security-Policy Restringir las fuentes de contenido permitidas
X-Content-Type-Options Reducir la interpretación incorrecta de tipos de contenido
X-Frame-Options Limitar la visualización en marcos

La plantilla está configurada para producir una coincidencia de severidad baja cuando falta alguna de las cabeceras seleccionadas.

Esta comprobación permite identificar determinadas configuraciones HTTP que podrían necesitar revisión.

Sin embargo, evaluar estas tres cabeceras no representa una auditoría completa de la seguridad de una aplicación.

⚙️ Configuración del escaneo

Los argumentos utilizados durante el análisis fueron:

-u http://127.0.0.1:5000 -t .nuclei/templates -rl 2 -c 1 -timeout 5 -retries 0 -no-interactsh -disable-update-check -jsonl -o artifacts/nuclei.jsonl 

Los parámetros más importantes cumplen las siguientes funciones:

  • -u: establece la dirección de la aplicación analizada.
  • -t: selecciona el directorio de plantillas.
  • -rl 2: limita la tasa a dos solicitudes por segundo.
  • -c 1: establece una concurrencia de uno.
  • -timeout 5: configura el tiempo máximo de espera.
  • -jsonl: permite generar resultados estructurados.

El análisis fue ejecutado contra una instancia temporal de EstadoSeguro disponible en 127.0.0.1:5000.

Esta configuración permite realizar comprobaciones controladas dentro de GitHub Actions, sin escanear directamente la aplicación pública alojada en Render.

📊 6. Resultados reales del análisis con Nuclei

Después de configurar y validar las plantillas, se ejecutó Nuclei v3.11.1 dentro del proceso automatizado.

Las dos plantillas fueron cargadas correctamente y se realizó el análisis sobre el servidor local.

✅ Resultados registrados

Comprobación Resultado
Herramienta Nuclei v3.11.1
Plantillas utilizadas 2
Objetivo analizado 127.0.0.1:5000
Coincidencias informativas 1
Hallazgos por ausencia de cabeceras 0
Vulnerabilidades reportadas por las plantillas 0
Formato de salida JSONL

Interpretación de resultados

La primera plantilla registró una coincidencia informativa identificada como:

estadosseguro-healthcheck

Esta coincidencia corresponde a la respuesta del endpoint /health, que cumplió las condiciones establecidas.

La segunda plantilla, denominada missing-security-headers.yaml, no produjo coincidencias relacionadas con la ausencia de las cabeceras seleccionadas.

Por lo tanto, no se reportaron vulnerabilidades dentro del alcance de las dos comprobaciones ejecutadas.

No obstante, es fundamental interpretar correctamente estos resultados.

⚠️ Una aplicación no puede considerarse completamente segura únicamente porque un escáner no haya reportado vulnerabilidades.

En este proyecto se verificaron determinadas propiedades HTTP. Para ampliar la evaluación sería necesario incorporar otras comprobaciones y categorías de seguridad.

Conservación de evidencias

Los resultados se generaron en formato JSONL, permitiendo su almacenamiento y revisión posterior.

GitHub Actions conserva los archivos del análisis como artefactos descargables.

Además, el repositorio incluye resultados de una ejecución anterior dentro del directorio:

docs/evidencias/github-actions-42974596625/

Estos registros permiten consultar la coincidencia informativa y revisar el comportamiento del servidor durante las verificaciones realizadas.

La conservación de resultados constituye una práctica importante para mantener trazabilidad sobre las actividades de análisis de seguridad.

⚙️ 7. Integración continua con GitHub Actions

Una vez desarrolladas las pruebas con Pytest y las plantillas de Nuclei, se implementó un workflow de GitHub Actions para automatizar ambas actividades.

La configuración se encuentra en el archivo:

.github/workflows/ci-security.yml

El workflow está preparado para ejecutarse cuando se realizan cambios en la rama main, se abren o actualizan solicitudes de incorporación de cambios, o se inicia manualmente.

🔄 Etapas del proceso automatizado

Etapa 1. Preparación del entorno

GitHub Actions prepara Python e instala las dependencias necesarias para ejecutar EstadoSeguro.

Etapa 2. Ejecución de pruebas

Se ejecuta Pytest para verificar los doce casos automatizados.

Etapa 3. Inicio temporal de Flask

Se inicia la aplicación en una instancia local disponible en 127.0.0.1:5000.

Etapa 4. Verificación de disponibilidad

El workflow comprueba que /health responda correctamente antes de continuar.

Etapa 5. Análisis con Nuclei

Se utiliza la integración oficial projectdiscovery/nuclei-action@v3 para ejecutar las dos plantillas personalizadas.

Etapa 6. Conservación de resultados

Se almacenan los registros y resultados del escaneo como artefactos de GitHub Actions.

✅ Resultado del workflow

La ejecución asociada al commit:

39d4412 — docs: prepara artículo Dev.to y evidencia verificada

finalizó con estado Success.

Durante el proceso se registraron 12 pruebas aprobadas y se completaron las comprobaciones de seguridad mediante Nuclei.

🔗 Consultar la ejecución verificada de GitHub Actions

Esta automatización facilita repetir las pruebas y comprobaciones cuando se incorporan cambios en el código.

Además, cada ejecución queda relacionada con una versión del repositorio, permitiendo revisar los resultados y los archivos generados.

Beneficios de la integración continua

La integración de GitHub Actions permitió mejorar tres aspectos importantes del proyecto:

Automatización: las pruebas y comprobaciones se ejecutan mediante un flujo definido.

Trazabilidad: los registros permiten revisar qué actividades se realizaron y a qué commit corresponden.

Reproducibilidad: las configuraciones almacenadas en el repositorio permiten repetir las verificaciones en ejecuciones posteriores.

De esta manera, el análisis de seguridad forma parte del proceso habitual de desarrollo, en lugar de ejecutarse únicamente como una actividad aislada.

☁️ 8. Publicación y despliegue automatizado en Render

Una vez completada la implementación y configuradas las verificaciones, se preparó el despliegue de EstadoSeguro en Render.

Esta plataforma permite conectar repositorios de GitHub y publicar aplicaciones web mediante configuraciones declarativas.

Para el proyecto se utilizó un archivo render.yaml, almacenado en la raíz del repositorio.

Configuración utilizada

services: - type: web name: estadosseguro runtime: python plan: free buildCommand: pip install -r requirements.txt startCommand: gunicorn app:app --bind 0.0.0.0:$PORT --workers 2 --threads 4 --timeout 60 healthCheckPath: /health autoDeployTrigger: checksPass envVars: - key: PYTHON_VERSION value: 3.12.10 - key: SECRET_KEY generateValue: true 

Esta configuración establece un servicio web Python y utiliza el plan gratuito de Render.

El comando buildCommand instala las dependencias necesarias, mientras que startCommand inicia la aplicación mediante Gunicorn.

La propiedad healthCheckPath: /health permite comprobar la disponibilidad del servicio.

Por su parte, autoDeployTrigger: checksPass configura los despliegues automáticos para esperar que las verificaciones de integración continua sean satisfactorias.

🌐 Resultado del despliegue

El repositorio se conectó a Render mediante un Blueprint, permitiendo publicar EstadoSeguro en una dirección accesible desde internet.

🔗 Acceder a EstadoSeguro en Render

Durante la verificación realizada el 11 de noviembre de 2026, la página principal y el endpoint /health respondieron correctamente con código HTTP 200.

Estos resultados permitieron comprobar que la aplicación se encontraba disponible públicamente durante la revisión.

Es importante distinguir los entornos utilizados:

  • GitHub Actions: ejecuta las pruebas y el análisis de Nuclei contra una instancia local.
  • Render: aloja la aplicación publicada y permite comprobar su disponibilidad desde internet.

El escaneo automatizado de Nuclei no se ejecutó directamente sobre el dominio público de Render, sino sobre una instancia controlada dentro del workflow.

Ventajas obtenidas

El despliegue mediante Render permitió publicar la aplicación utilizando un repositorio público y mantener su configuración como código.

Asimismo, la integración con GitHub Actions permite combinar las verificaciones automatizadas con una política de despliegue condicionada a los resultados de CI.

Esta implementación demuestra la utilidad de conectar las actividades de desarrollo, verificación y publicación mediante herramientas automatizadas.

🏆 9. Conclusiones y aprendizajes

El desarrollo de EstadoSeguro permitió aplicar diferentes conceptos de calidad de software, seguridad informática e integración continua mediante tecnologías accesibles.

A partir del proceso realizado, se establecen las siguientes conclusiones.

✅ Primera conclusión: automatización de la calidad

La utilización de Pytest y GitHub Actions permitió ejecutar doce pruebas automatizadas, las cuales finalizaron satisfactoriamente.

La integración de estas herramientas facilitó la verificación reproducible de las funcionalidades principales y determinados controles de seguridad.

Este resultado demuestra la importancia de incorporar pruebas automatizadas durante el desarrollo de aplicaciones web.

✅ Segunda conclusión: análisis de seguridad con Nuclei

La integración de Nuclei permitió implementar dos comprobaciones HTTP personalizadas y ejecutarlas dentro de GitHub Actions.

El análisis registró una coincidencia informativa de disponibilidad y no produjo hallazgos relacionados con la ausencia de las cabeceras evaluadas.

Estos resultados permitieron comprender la diferencia entre un resultado informativo y una posible vulnerabilidad.

Asimismo, demostraron la importancia de definir correctamente el alcance del análisis y evitar interpretar la ausencia de hallazgos como una garantía general de seguridad.

✅ Tercera conclusión: despliegue y automatización en la nube

La publicación de EstadoSeguro en Render permitió disponer de una aplicación web accesible públicamente mediante una dirección URL.

La configuración del servicio utilizando render.yaml facilitó la definición de los parámetros necesarios para su ejecución y estableció una política de despliegue vinculada con las verificaciones de CI.

Esta experiencia demuestra cómo combinar control de versiones, integración continua y servicios en la nube para desarrollar proyectos más organizados y verificables.

💡 Reflexión final

Uno de los principales aprendizajes obtenidos durante este proyecto fue comprender que la seguridad no debe considerarse una actividad exclusiva de las etapas finales del desarrollo.

La integración de herramientas como Pytest, Nuclei, GitHub Actions y Render demuestra que es posible incorporar verificaciones de calidad y seguridad dentro de un mismo proceso.

Sin embargo, también resulta fundamental reconocer las limitaciones del análisis realizado.

Las dos plantillas utilizadas no evaluaron exhaustivamente categorías como inyección, autenticación, autorización, gestión de sesiones o vulnerabilidades de dependencias.

Por ello, una evaluación de seguridad más amplia requeriría nuevas comprobaciones y metodologías adicionales.

La seguridad del software debe entenderse como un proceso continuo de desarrollo, evaluación y mejora, y no como el resultado de ejecutar una única herramienta.

📚 10. Referencias y recursos

OWASP Foundation. Vulnerability Scanning Tools.

https://community.owasp.org/Vulnerability_Scanning_Tools

ProjectDiscovery. Nuclei — Vulnerability Scanner.

https://github.com/projectdiscovery/nuclei

ProjectDiscovery. Nuclei Action v3.

https://github.com/projectdiscovery/nuclei-action/blob/v3/README.md

GitHub. GitHub Actions Documentation.

https://docs.github.com/en/actions

Render. Blueprint YAML Reference.

https://render.com/docs/blueprint-spec

Pallets Projects. Flask Documentation.

https://flask.palletsprojects.com/

pytest-dev. Pytest Documentation.

https://docs.pytest.org/

🔗 Recursos del proyecto EstadoSeguro

💻 Código fuente: Repositorio público en GitHub

🌐 Aplicación web: EstadoSeguro en Render

⚙️ Resultados de automatización: GitHub Actions

Artículo elaborado como parte de una actividad académica del curso de Calidad de Software, noviembre de 2026.