En esta tarea usaremos Playwright, una herramienta poderosa para automatizar navegadores e interactuar con aplicaciones web. Playwright fue desarrollada como una alternativa mejorada a Puppeteer, ofreciendo mejor soporte entre navegadores y capacidades de automatización avanzadas.


Aplicación Vulnerable

Usaremos una aplicación propia de saludos que permite a los usuarios introducir un nombre y mostrar un mensaje personalizado.

Vulnerability Scanning

La app consiste de un campo de texto para el nombre y un botón de subida que sube el mensaje al servidor que devuelve el mensaje personalizado.


Por qué Automatizar con Playwright

Aunque ZAP puede escanear aplicaciones directamente, hay escenarios donde automatizar las interacciones del navegador con cualquier herramienta ofrece mejor cobertura. A veces las aplicaciones web tienen múltiples campos de introducción de datos con validación personalizada y formularios de subida dinámicos que requieren interacción real del usuario, las cuales ZAP sólo puede replicar.


Configurar el Entorno

Antes de escribir código, debemos configurar ZAP para permitir a Playwright interactuar con el navegador y realizar un escaneo de vulnerabilidades. Para hacer esto, habilitaremos el proxy de ZAP y también obtendremos una clave API para usar las funcionalidades de ZAP como se muestra:

  • En la máquina virtual, abre ZAP y navega hacia Tools > Options > Network > Local Proxy. Asegúrate de que la dirección proxy esté configurada en localhost y al puerto 8080.

Vulnerability Scanning

  • Después, para acceder a las funcionalidades de ZAP remotamente en Python, necesitaremos la clave API navegando a Tools > Options > API.

Vulnerability Scanning


Conectar con la API

Ahora que el entorno está configurado, usaremos Python para interactuar con la API de ZAP. Creamos el script play.py:

python
from playwright.sync_api import sync_playwright, Playwright
from zapv2 import ZAPv2, reports
import time
import os
import sys

class SilentOutput:
    def write(self, msg): pass
    def flush(self): pass

sys.stdout = SilentOutput()  

# Config
ZAP_KEY = "kcsbj07b6u7hhii6h3b772ia90"
PROXY = "http://localhost:8080"
TARGET_URL = "http://10.10.215.190:5000/"
xss_tests = [
    "<script>alert('XSS')</script>",
    "<img src=x onerror=alert('XSS')>",
    "<svg/onload=alert('XSS')>",
    "\"><script>alert('XSS')</script>",
]

def execute_automation(playwright: Playwright):
    zap = ZAPv2(apikey=ZAP_KEY, proxies={'http': PROXY})
    zap.core.new_session(name="silent_passive", overwrite=True)

    browser = playwright.firefox.launch(headless=True)
    context = browser.new_context(
        ignore_https_errors=True,
        proxy={"server": PROXY}
    )
    page = context.new_page()

    sys.stdout = sys.__stdout__

    for payload in xss_tests:
        print(f"Injecting Payload: {payload}")
        page.once("dialog", lambda dialog: dialog.dismiss())
        page.goto(f"{TARGET_URL}?name={payload}")
        time.sleep(1)

    sys.stdout = SilentOutput()
    while int(zap.pscan.records_to_scan) > 0:
        time.sleep(1)

    desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
    zap_reporter = reports(zap)
    zap_reporter.generate(
        title="Silent Passive XSS Scan",
        template="traditional-pdf",
        description="Clean scan",
        reportfilename="zap_passive_silent_report.pdf",
        reportdir=desktop_path,
        display=False,
    )

    browser.close()

with sync_playwright() as pw:
    execute_automation(pw)

En el código de arriba, asegúrate de actualizar el valor de la IP. Este código tiene las siguientes funciones/variables importantes:

  • ZAP_KEY, PROXY y TARGET_URL son variables para globales constantes.
  • xss_tests es un array que contiene una lista de payloads XSS usados para comprobar vulnerabilidades inyectándolos en la aplicación.
  • La función execute_automation() automatiza las interacciones del navegador usando Playwright visitando la aplicación web e inspeccionando el payload XSS.
  • Finalmente, zap_reporter.generate() genera un reporte de seguridad detallado resumiendo vulnerabilidades encontradas durante el escaneo.