En la lección anterior dejamos ZAP listo para trabajar: el certificado raíz confiado, el proxy enrutando el tráfico de BazarNube y un contexto con scope y autenticación bien definidos. Toda esa preparación tenía un objetivo: llegar hasta las zonas donde de verdad hay riesgo. Ahora ponemos la maquinaria en marcha. En esta lección recorreremos el flujo completo de un escaneo dinámico (DAST) sobre el staging de BazarNube: exploraremos la aplicación con el spider y el AJAX Spider, dejaremos trabajar al escáner pasivo, lanzaremos el escáner activo con una política adecuada, aprenderemos a interpretar las alertas por riesgo y confianza, haremos triage de falsos positivos y generaremos informes que mapeen los hallazgos al Top Ten 2021 y al backlog del equipo.

Nota ético-legal (imprescindible). Un escaneo activo envía ataques reales (payloads de inyección, cargas que modifican datos, peticiones masivas). Ejecútalo únicamente contra sistemas de tu propiedad o con permiso explícito por escrito. En este curso siempre trabajamos sobre https://staging.bazarnube.local, un entorno propio, aislado y con datos ficticios. Nunca apuntes ZAP en modo attack a producción ni a terceros como la pasarela pay.tercero.com.

Contenido

  1. El flujo de un escaneo de principio a fin
  2. Fase 1: explorar con el Spider y el AJAX Spider
  3. Fase 2: el escáner pasivo
  4. Fase 3: el escáner activo y las políticas de escaneo
  5. Interpretar alertas: riesgo y confianza
  6. Triage de falsos positivos
  7. Mapeo de alertas de ZAP al Top Ten 2021 y al backlog de BazarNube
  8. Generación de informes (HTML, JSON, Markdown)
  9. Errores comunes y consejos
  10. Ejercicios
  11. Conclusión

El flujo de un escaneo de principio a fin

Un escaneo DAST no es un botón mágico: es una secuencia. ZAP solo puede atacar lo que conoce, así que primero hay que descubrir la superficie (URLs, formularios, parámetros, endpoints de API) y después probarla. El orden es siempre el mismo:

flowchart LR
    A[Contexto y auth listos] --> B[Explorar: Spider]
    B --> C[Explorar: AJAX Spider]
    C --> D[Escaneo pasivo automatico]
    D --> E[Escaneo activo con policy]
    E --> F[Triage de alertas]
    F --> G[Informe HTML / JSON / MD]
    G --> H[Backlog de BazarNube]

Cada fase alimenta a la siguiente: cuanto mejor sea la exploración, más completo será el árbol de sitios (Sites tree) y más superficie tendrá el escáner activo para probar. Un escaneo con mala cobertura da una falsa sensación de seguridad: "0 alertas altas" no significa nada si el spider no llegó al 60% de la aplicación.

Fase 1: explorar con el Spider y el AJAX Spider

Spider tradicional

El Spider parte de una o varias URLs semilla y sigue los enlaces href, src y las acciones de formulario que encuentra en el HTML. Es rápido y barato, pero solo ve lo que está en el HTML estático. Para lanzarlo sobre nuestro contexto autenticado:

  1. Clic derecho sobre el nodo raíz de BazarNube en el Sites tree > Attack > Spider....
  2. Selecciona el Context y el User que definimos en 06-02, para que explore ya autenticado como vendedor.
  3. Deja marcada la opción de respetar el scope del contexto.

Desde la línea de comandos vía API (lo veremos en detalle en 06-04) sería:

# Semilla de exploracion dentro del scope de staging
curl "http://localhost:8080/JSON/spider/action/scan/?apikey=$ZAP_KEY&contextName=BazarNube&url=https://staging.bazarnube.local/"

AJAX Spider

BazarNube tiene un frontend React: gran parte de la navegación y los datos se cargan por JavaScript, y el catálogo se pinta con llamadas fetch a la API. El Spider tradicional no ejecuta JavaScript, así que se perdería casi todo el marketplace. Para eso está el AJAX Spider, que controla un navegador real (Firefox/Chrome headless) y explora la aplicación como lo haría un usuario, disparando eventos y capturando las peticiones XHR.

Aspecto Spider tradicional AJAX Spider
Ejecuta JavaScript No Sí (navegador real)
Velocidad Muy rápido Lento
Cobertura en SPA (React) Baja Alta
Consumo de recursos Bajo Alto (CPU/RAM)
Cuándo usarlo Sitios clásicos, APIs enlazadas SPAs, mucho contenido dinámico

Regla práctica para BazarNube: ejecuta primero el Spider tradicional (barato, cubre la API y las rutas server-rendered del legacy Java) y a continuación el AJAX Spider para el frontend React. La unión de ambos da la mejor cobertura.

Para las APIs REST/GraphQL, la mejor "exploración" no es el spider sino importar la definición: ZAP puede consumir un fichero OpenAPI/Swagger o una colección, poblando el árbol con todos los endpoints y sus parámetros. Si BazarNube publica openapi.json, impórtalo antes de escanear.

Fase 2: el escáner pasivo

Mientras exploras (y mientras navegas manualmente por el proxy), el escáner pasivo trabaja en segundo plano: no envía ni una sola petición extra. Se limita a observar las peticiones y respuestas que ya pasan por ZAP y a detectar problemas visibles sin atacar:

  • Cabeceras de seguridad ausentes (Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options).
  • Cookies sin Secure, HttpOnly o SameSite.
  • Fugas de información (versiones de servidor, comentarios, mensajes de error, tokens en URL).
  • Recursos servidos por HTTP dentro de HTTPS (mixed content).

Como no ataca, el escaneo pasivo es seguro incluso en producción y es el motor detrás del modo safe que vimos en 06-01. Es el primer sitio donde mirar: muchas de las "victorias rápidas" de BazarNube (cabeceras y flags de cookie) salen aquí sin coste ni riesgo.

Fase 3: el escáner activo y las políticas de escaneo

El escáner activo es donde ZAP realmente ataca: coge cada URL y cada parámetro descubiertos e inyecta payloads para provocar comportamientos vulnerables (comillas para SQLi, scripts para XSS, rutas para path traversal, etc.). Por eso solo se lanza sobre staging propio.

Anatomía de una política de escaneo (Scan Policy)

Una Scan Policy define qué familias de ataque se ejecutan y con qué intensidad. Se gestiona en Analyse > Scan Policy Manager. Sus dos ejes son:

  • Threshold (umbral): cómo de "seguro" debe estar ZAP antes de reportar. Low reporta más (y genera más falsos positivos); High reporta solo cuando está muy seguro. Off desactiva esa familia.
  • Strength (fuerza): cuántos payloads prueba por parámetro. Low es rápido; Insane es exhaustivo pero lento y ruidoso.
Familia de reglas activas Threshold Strength Justificación en BazarNube
SQL Injection Medium High Hay backend PostgreSQL y consultas legacy Java; prioritario
Cross Site Scripting Medium High Reflejado y almacenado; el catálogo pinta datos de vendedor
Path Traversal / LFI Medium Medium Descarga de facturas por parámetro de fichero
Server Side Request Forgery Medium Medium Servicio de "importar producto por URL"
Remote Code Execution Medium Medium Cobertura del Top Ten
External redirect Low Low Ruido bajo, útil detectarlo

Crea una política a medida (por ejemplo BazarNube-Web) en lugar de usar la de por defecto: acota el tiempo de escaneo y evita ruido irrelevante. Para lanzar el activo: clic derecho sobre el contexto > Attack > Active Scan..., elige el User autenticado y la Policy creada.

# Escaneo activo por API, con contexto, usuario y politica propios
curl "http://localhost:8080/JSON/ascan/action/scan/?apikey=$ZAP_KEY&contextId=1&userId=1&scanPolicyName=BazarNube-Web&recurse=true"

Interpretar alertas: riesgo y confianza

Cada hallazgo es una alerta con dos ejes independientes que no hay que confundir:

  • Riesgo (Risk): el impacto potencial si es real. Niveles: High, Medium, Low, Informational.
  • Confianza (Confidence): cómo de seguro está ZAP de que no es un falso positivo. Niveles: Confirmed, High, Medium, Low, False Positive (este último lo marcas tú tras el triage).

Un hallazgo High risk / Low confidence no se ignora: se verifica manualmente, porque si se confirma es de los más graves. Y un Low risk / High confidence puede ser una corrección trivial que conviene cerrar ya. Prioriza cruzando ambos ejes:

flowchart TD
    A[Nueva alerta] --> B{Risk?}
    B -->|High/Medium| C{Confidence?}
    B -->|Low/Info| D[Backlog normal o victoria rapida]
    C -->|High/Confirmed| E[Verificar y abrir hallazgo prioritario]
    C -->|Low/Medium| F[Reproducir manualmente antes de reportar]

Triage de falsos positivos

DAST genera falsos positivos: es normal y esperable. El triage es el trabajo de separar lo real de lo espurio antes de molestar a Lucía o a Marc con un ticket. Proceso recomendado por alerta:

  1. Lee la evidencia que da ZAP: la petición atacante y el fragmento de respuesta que disparó la regla (pestaña Response con el highlight).
  2. Reprodúcelo con el Request Editor o curl: ¿el comportamiento se sostiene fuera de ZAP?
  3. Contrasta con el código cuando puedas: un XSS reflejado reportado sobre un valor que el frontend escapa con React puede ser falso.
  4. Decide: si es real, se queda; si es espurio, clic derecho > Mark as False Positive (o súbele el threshold de esa regla). Documenta por qué.

Un falso positivo mal cerrado es tan peligroso como no escanear: si marcas como FP algo real, lo entierras. Deja siempre una nota del razonamiento.

Mapeo de alertas de ZAP al Top Ten 2021 y al backlog de BazarNube

Las alertas de ZAP hablan el idioma de las scan rules; el negocio y el backlog hablan el idioma del Top Ten 2021 (que vimos en M3). Traducir de uno a otro es lo que convierte un informe técnico en trabajo priorizado. Esta es la tabla de correspondencia para BazarNube:

Alerta de ZAP Riesgo típico Categoría OWASP Top Ten 2021 Hallazgo del backlog de BazarNube
SQL Injection High A03: Injection BZN-112 login del legacy Java concatena SQL
Cross Site Scripting (Reflected) High A03: Injection BZN-087 buscador refleja q sin escapar
Path Traversal High A01: Broken Access Control BZN-140 descarga de factura por file=
Absence of Anti-CSRF Tokens Medium A01: Broken Access Control BZN-095 formularios del panel vendedor
Server Side Request Forgery High A10: SSRF BZN-131 "importar producto por URL"
Application Error Disclosure Low A05: Security Misconfiguration BZN-060 stack traces de Spring Boot
CSP Header Not Set Medium A05: Security Misconfiguration BZN-041 falta CSP en el frontend React
Cookie without HttpOnly/SameSite Low A05: Security Misconfiguration BZN-039 cookie de sesión del panel
Vulnerable JS Library Medium A06: Vulnerable Components BZN-118 librería frontend desactualizada

Ojo con el IDOR. El Broken Access Control de tipo IDOR (acceso a un pedido ajeno cambiando el id) que estudiamos en M3 es difícil de detectar para un DAST genérico, porque ZAP no sabe qué recurso "debería" ver cada usuario. ZAP tiene el complemento Access Control Testing, pero requiere que definas dos usuarios con roles distintos y las reglas de acceso esperadas. No confíes en el escáner activo para el control de acceso: complétalo con pruebas manuales o de negocio.

Generación de informes (HTML, JSON, Markdown)

Con el triage hecho, se genera el informe. Desde la GUI: Report > Generate Report.... ZAP ofrece plantillas según el destinatario:

Formato Plantilla ZAP típica Destinatario Uso
HTML traditional-html / risk-confidence-html Lucía, dirección Lectura humana, evidencias visibles
JSON traditional-json Automatización / SIEM Parsear, comparar entre builds
Markdown traditional-md Backlog / repositorio Pegar en un ticket o PR
XML traditional-xml Herramientas legacy Integración con otras suites

Por API o CLI (anticipando 06-04):

# Informe HTML por riesgo y confianza
curl "http://localhost:8080/OTHER/core/other/htmlreport/?apikey=$ZAP_KEY" -o zap-bazarnube.html

# Volcado JSON de todas las alertas para procesar en el pipeline
curl "http://localhost:8080/JSON/core/view/alerts/?apikey=$ZAP_KEY&baseurl=https://staging.bazarnube.local" -o alerts.json

El informe no es el final del trabajo: es la entrada del backlog. Cada alerta confirmada se convierte en un BZN-xxx con su categoría del Top Ten, su evidencia y su prioridad por riesgo.

Errores Comunes y Consejos

  • Lanzar el activo sin haber explorado. Si el árbol de sitios está vacío, el escáner activo no ataca nada. Explora (Spider + AJAX Spider o import OpenAPI) antes.
  • Olvidar la autenticación. Si ZAP pierde la sesión a mitad de escaneo, todo lo autenticado queda sin probar. Verifica los indicadores de sesión del contexto (06-02) y añade /logout a las exclusiones.
  • Confundir riesgo con confianza. Son ejes distintos. Un High risk / Low confidence se verifica, no se descarta.
  • Escanear producción "solo un poco". No existe un activo "suave" seguro: modifica datos y genera carga. Solo staging propio.
  • Fiarse del "0 altas". Sin cobertura, cero alertas no es tranquilidad. Mira siempre cuántas URLs se exploraron.
  • No documentar los falsos positivos. Un FP sin justificación es deuda oculta; el siguiente que lo vea no sabrá si fiarse.
  • Esperar que ZAP encuentre IDOR/lógica de negocio. El DAST cubre inyecciones y misconfig; el control de acceso fino y la lógica requieren prueba manual.

Ejercicios

Ejercicio 1. El equipo se queja de que ZAP "no encuentra casi nada" en el catálogo de BazarNube, que es un React SPA. El árbol de sitios muestra solo la home y /login. ¿Qué ha fallado en la fase de exploración y cómo lo corriges?

Ejercicio 2. ZAP reporta una alerta "Cross Site Scripting (Reflected)" con Risk: High y Confidence: Low sobre el parámetro q del buscador. Describe el proceso de triage paso a paso antes de abrir (o no) el ticket BZN-087.

Ejercicio 3. Tienes que priorizar tres alertas para la reunión con Lucía: (A) SQL Injection, High/Confirmed; (B) CSP Header Not Set, Medium/High; (C) Application Error Disclosure, Low/High. Ordénalas y mapea cada una a su categoría del Top Ten 2021.

Soluciones

Solución 1. Solo se ejecutó el Spider tradicional, que no ejecuta JavaScript, así que no vio el catálogo cargado por React. La corrección es lanzar el AJAX Spider (que usa un navegador real) sobre el mismo contexto autenticado y, si BazarNube publica una definición OpenAPI de su API, importarla para poblar todos los endpoints. Después se relanza el escaneo con el árbol ya completo.

Solución 2. (1) Abrir la alerta y leer la evidencia: la petición inyectada y el fragmento de respuesta resaltado. (2) Reproducir con el Request Editor o curl para ver si el payload vuelve sin escapar en la respuesta HTML (no solo en un JSON que el front nunca renderiza como HTML). (3) Comprobar si el valor termina realmente en el DOM sin escapar; si React lo pinta con {q} lo escapa por defecto (posible FP), pero si se usa dangerouslySetInnerHTML o se inserta server-side, es real. (4) Si se confirma, abrir BZN-087 como A03 Injection prioritario; si es espurio, marcar False Positive con nota del motivo.

Solución 3. Orden de prioridad: A > B > C.

  • (A) SQL Injection, High/Confirmed -> A03: Injection. Máxima prioridad: confirmada y de alto impacto.
  • (B) CSP Header Not Set, Medium/High -> A05: Security Misconfiguration. Importante y de corrección barata.
  • (C) Application Error Disclosure, Low/High -> A05: Security Misconfiguration. Real pero de bajo impacto; victoria rápida.

Conclusión

Ya dominas el ciclo completo de un escaneo dinámico en ZAP: explorar con Spider y AJAX Spider, dejar trabajar al pasivo, atacar con el activo usando una política a medida, interpretar las alertas por riesgo y confianza, hacer triage de falsos positivos, mapear cada hallazgo al Top Ten 2021 y al backlog de BazarNube, y empaquetarlo en un informe accionable. Todo ello, siempre, contra tu propio staging.

Hacer esto a mano cada vez que se toca el código no escala. En la última lección del módulo, 06-04 Automatización de Pruebas de Seguridad, llevaremos ZAP al pipeline: zap-baseline.py y zap-full-scan.py con Docker, el Automation Framework en YAML, la API en modo daemon, y pipelines completos de GitHub Actions y GitLab CI que ejecutan un DAST sobre BazarNube en cada cambio, publican el informe como artefacto y rompen el build cuando aparecen vulnerabilidades por encima del umbral.

Curso de OWASP: Directrices y Estándares para la Seguridad en Aplicaciones Web

Módulo 1: Introducción a OWASP

Módulo 2: Principales Proyectos de OWASP

Módulo 3: OWASP Top Ten 2021 en Profundidad

Módulo 4: OWASP ASVS (Application Security Verification Standard)

Módulo 5: OWASP SAMM (Software Assurance Maturity Model)

Módulo 6: OWASP ZAP (Zed Attack Proxy)

Módulo 7: Buenas Prácticas y Recomendaciones

Módulo 8: Ejercicios Prácticos y Casos de Estudio

Módulo 9: Evaluación y Certificación

© Copyright 2026. Todos los derechos reservados