
Herramienta automatizada de evaluación de WAF que detecta proveedores de firewall, prueba 19 categorías de ataque con payloads de evasión avanzados y proporciona análisis de bypass codificado por colores a través de CLI, Cloudflare Worker o Docker.
# Comprobador de WAF
[](https://github.com/SecH0us3/waf-checker/releases)
[](https://github.com/SecH0us3/waf-checker/releases)
[](packages/core)
[](packages/cli)
[]()
Este proyecto te ayuda a comprobar qué tan bien tu Firewall de Aplicaciones Web (WAF) protege tu producto contra ataques web comunes. Se puede ejecutar como un Cloudflare Worker (con una interfaz web interactiva integrada) o como una herramienta CLI independiente de Node.js.
## 🧪 Cobertura de Pruebas y Estado
Todos los paquetes están exhaustivamente probados con suites automatizadas de pruebas unitarias, de integración, basadas en propiedades (fuzzing con fast-check), de resiliencia de red y de ingeniería inversa (100% de cumplimiento de seguridad SSRF, técnicas de evasión de protocolos y formateadores de informes):
| Paquete | Cobertura de líneas | Sentencias | Funciones | Suite de pruebas |
| :--- | :---: | :---: | :---: | :---: |
| [**`@waf-checker/core`**](https://github.com/sech0us3/waf-checker/blob/main/packages/core) | `93.0%` 🟢 | `92.6%` | `96.4%` | 🟢 282 superadas |
| [**`@waf-checker/cli`**](https://github.com/sech0us3/waf-checker/blob/main/packages/cli) | `93.5%` 🟢 | `92.8%` | `96.7%` | 🟢 54 superadas |
| [**`@waf-checker/worker`**](https://github.com/sech0us3/waf-checker/blob/main/packages/worker) | `Superadas` 🟢 | — | — | 🟢 30 superadas |
| **Suite total del monorepo** | **`93.2%`** | **`92.7%`** | **`96.6%`** | **🟢 366 pruebas superadas** |
## Características
### Pruebas Principales
- Introduce una URL objetivo, selecciona los métodos HTTP (GET, POST, etc.) y las categorías de ataque.
- Envía solicitudes con cargas útiles de ataque (en parámetros, cabeceras o como rutas de archivo).
- Resultados en terminal y web con código de colores: 🟢 403/BLOQUEADO = bloqueado, 🔴 2xx/5xx = posible evasión, 🟠 3xx = redirección.
- Resultados mostrados en una tabla filtrable con detalles para cada carga útil.
### 🕵️ Ingeniería Inversa de WAF y Matriz CRS (`--reverse`)
- **Mapeo del Conjunto de Reglas Principales de OWASP (CRS v3/v4)**: Audita los IDs de reglas activas frente a las deshabilitadas (`920xxx`, `921xxx`, `930xxx`, `931xxx`, `932xxx`, `933xxx`, `934xxx`, `941xxx`, `942xxx`, `943xxx`, `944xxx`) con Niveles de Paranoia (PL1-PL4).
- **Detección del Límite del Cuerpo de Inspección**: Sondeo mediante búsqueda binaria (8KB – 128KB, precisión ~1KB) para identificar los límites de truncamiento del búfer.
- **Detección del Modo de Puntuación de Anomalías**: Sondea el modo de puntuación colaborativa frente al modo de bloqueo estricto por regex e identifica los umbrales de puntuación.
- **Sondeo Seguro de Límite de Tasa**: Aumento gradual seguro hasta 30 req/s con terminación anticipada inmediata al recibir HTTP 429 y extracción de `Retry-After`.
### 🛡️ Parcheo Virtual de WAF y Auto-Remediación (comando `--patch` / `patch`)
- **Mitigación Instantánea**: Transforma automáticamente los bypasses de WAF detectados (HTTP 200) en reglas de firewall listas para desplegar, configuraciones de proxy inverso e Infraestructura como Código (Terraform HCL / Cloud CLI).
- **Plataformas Compatibles (11 Dialectos)**:
- **Cloudflare WAF**: Expresiones Wirefilter (`http.request.uri.query contains ...` / `matches ...`) y Terraform HCL `cloudflare_ruleset`.
- **AWS WAF v2**: Declaraciones de Reglas JSON Nativas (`ByteMatchStatement`, `RegexPatternSet`, `OrStatement`) y Terraform HCL `aws_wafv2_rule_group`.
- **Google Cloud Armor**: Expresiones CEL (`request.path.matches(...)`, `request.headers[...]`), comandos CLI `gcloud compute security-policies` y Terraform `google_compute_security_policy`.
- **Azure WAF (Front Door y App Gateway)**: Definiciones JSON de Reglas Personalizadas, comandos CLI `az network front-door waf-policy` y Terraform `azurerm_cdn_frontdoor_firewall_policy`.
- **ModSecurity y OWASP Coraza**: Directivas `SecRule` compatibles con OWASP CRS (SecLang) con colapso de tokens `@pm`. Compatible mediante `--patch modsecurity` o `--patch coraza`.
- **NGINX**: Bloques de configuración nativos `location ~* \.(ext)$ { return 403; }`, `location ~ /\.(git|svn)` y `map`.
- **HAProxy**: ACLs nativas de alto rendimiento (`path_end -i`, `path_beg -i`, `query -m sub -i`, `req.hdr()`) con `http-request deny deny_status 403`.
- **Caddy Server**: Matchers nombrados idiomáticos de Caddyfile (`@waf_patch_*`) con expresiones CEL (`expression {http.request.uri.query}.matches(...)`) y `respond 403`.
- **Apache HTTP Server**: Reglas `mod_rewrite` (`RewriteCond %{QUERY_STRING}` / `%{REQUEST_URI}` / `%{HTTP_USER_AGENT}` + `RewriteRule ^ - [F,L]`) para `httpd.conf`, `<VirtualHost>` o `.htaccess`. Compatible mediante `--patch apache`.
- **Envoy Proxy**: Entradas de ruta que coinciden con `:path`/cabeceras mediante RE2 `safe_regex` con `direct_response: 403` (o forward-and-tag en modo simulación) para un virtual_host de route_configuration. Compatible mediante `--patch envoy`.
- **Kubernetes Ingress (K8s)**: Manifiestos YAML `kind: Ingress` listos para producción con anotaciones `nginx.ingress.kubernetes.io/server-snippet`.
- **Defensa de Doble Nivel**:
- **Hotfix Estricto**: Firmas de tokens exactas con **0% de riesgo de falsos positivos** para respuesta inmediata a incidentes zero-day.
- **Patrón Heurístico**: Expresiones regulares generalizadas que cubren toda la estructura de la clase de vulnerabilidad.
- **Web UI Remediation Studio**: Modal de panel interactivo con vistas previas en vivo para todos los proveedores, copia al portapapeles con 1 clic, alternadores de formato y exportación de archivos.
### Categorías de Ataque (28 en total)
Inyección SQL, XSS, Inyección de Comandos, Path Traversal, SSRF, Inclusión de Archivos Locales, Archivos Sensibles, Redirección Abierta, SSTI, XXE, Inyección NoSQL, Inyección GraphQL, Ataque JWT (Cabecera), Ataque JWT (Parámetro), Contaminación de Prototipos (Cuerpo JSON), Contaminación de Prototipos (URL/Parámetro), Inyección LDAP, Inyección XPath, Inyección de Fórmulas en Hojas de Cálculo, Log4Shell (JNDI), Inyección CRLF, Contaminación de Parámetros HTTP, User-Agent, Bypass de IP, Contrabando de Solicitudes HTTP, Envenenamiento de Caché Web, Bypass UTF8/Unicode, Bypass del Límite de Inspección de WAF (Padding).
### Detección de WAF
- Detección automática del tipo de WAF antes de las pruebas (Cloudflare, AWS WAF, OWASP Coraza, BunkerWeb, ModSecurity, Akamai, Imperva, F5 BIG-IP, etc.).
- Sugiere técnicas de bypass específicas según el WAF detectado.
- Puede cambiar automáticamente a payloads avanzados específicos del WAF.
### Payloads y Codificación Avanzados
- Payloads de Bypass de WAF — doble codificación, unicode, mayúsculas y minúsculas mezcladas, inyección de comentarios, payloads poliglotas.
- Payloads Mejorados — técnicas de evasión modernas.
- Variaciones de Codificación — codificación URL, Unicode, Entidad HTML, Hex, Octal, Base64 con combinaciones automáticas.
- Bypasses específicos de WAF para Cloudflare, AWS WAF, ModSecurity.
### Manipulación del protocolo HTTP
- HTTP Verb Tampering — probar métodos HTTP poco comunes.
- Parameter Pollution — duplicar y dividir parámetros entre query/body.
- Content-Type Confusion — tipos de contenido alternativos para eludir reglas.
- Cabeceras de Request Smuggling.
- Variaciones de Host Header Injection.
- HTTP Method Override mediante cabeceras (`X-HTTP-Method-Override`, etc.).
### Pruebas por lotes
- Probar múltiples URL a la vez.
- Concurrencia y retardo configurables entre solicitudes.
- Seguimiento del progreso en tiempo real.
### 🔀 Diferenciación de regresiones (`--compare` / `--fail-on-regression`)
- Comparar un escaneo con un informe JSON guardado previamente para revelar **nuevos bypasses** (bloqueados antes, ahora no), payloads **recién bloqueados** y pruebas añadidas/eliminadas.
- Puerta de CI (`--fail-on-regression`) que falla solo ante un *empeoramiento* de la postura del WAF, no ante la lista completa de resultados — ideal para detectar la deriva de los conjuntos de reglas gestionados.
---
## Estructura del proyecto
El proyecto está estructurado como un monorepo de NPM Workspaces:
- [**`packages/core/`**](file:///Users/alex/src/waf-checker/packages/core): La librería principal de pruebas de seguridad, definición de payloads, firmas de fingerprinting de WAF y codificadores de ofuscación.
- [**`packages/worker/`**](file:///Users/alex/src/waf-checker/packages/worker): Paquete de Cloudflare Worker que sirve la interfaz web estática HTML/JS y los endpoints de API JSON.
- [**`packages/cli/`**](file:///Users/alex/src/waf-checker/packages/cli): Herramienta de interfaz de línea de comandos de Node.js para ejecutar auditorías directamente desde tu terminal.
---
## Instalación y compilación
Desde el directorio raíz, instala las dependencias y compila todos los workspaces:
```bash
npm install
npm run build
```
## Cómo ejecutar
### 1. Versión web (Cloudflare Worker)
Para ejecutar el servidor de desarrollo del Worker localmente (requiere Wrangler):
```bash
npm run dev:worker
```
La interfaz web será accesible en `http://localhost:8787` (u otro puerto si el 8787 está ocupado).
Para desplegar el Worker en Cloudflare:
```bash
npx wrangler deploy --workspace=packages/worker
```
El Worker necesita el plan **Workers Paid**: las páginas de escaneo y auditoría están dimensionadas para sus 10.000 subpeticiones por petición (`[limits] subrequests` en `wrangler.toml`, `WORKER_SUBREQUEST_LIMIT` en `packages/core/src/check.ts`). El plan Free solo permite 50 subpeticiones externas por petición: una página de escaneo con la prueba de omisión de User-Agent (activada por defecto en la UI) o con redirecciones seguidas supera ese límite.
### 2. Versión CLI (Node.js)
#### Instalarlo como comando global `waf-checker` (recomendado)
Después de `npm install && npm run build` en la raíz del repositorio, enlaza la CLI para que se ejecute
desde **cualquier directorio** — sin `cd` al repositorio y sin rutas largas `node .../dist`:
```bash
# Expose `waf-checker` on your PATH from the built workspace
npm link --workspace @waf-checker/cli
# …now, from anywhere:
waf-checker --help
waf-checker check https://example.com
# Uninstall later with:
npm rm -g @waf-checker/cli
```
El paquete publicado incluye su código, por lo que también puedes instalar una compilación empaquetada de forma global sin el repositorio: `npm pack --workspace @waf-checker/cli` y luego `npm i -g ./waf-checker-cli-*.tgz`.
#### Autocompletado de shell (bash / zsh / fish)
`waf-checker completion <shell>` imprime un script de autocompletado (omite `<shell>` para detectarlo automáticamente desde `$SHELL`):
```bash
# bash
waf-checker completion bash | sudo tee /etc/bash_completion.d/waf-checker
# or, without root: echo 'source <(waf-checker completion bash)' >> ~/.bashrc
# zsh (into a directory on your $fpath)
waf-checker completion zsh > "${fpath[1]}/_waf-checker"
# fish
waf-checker completion fish > ~/.config/fish/completions/waf-checker.fish
```
#### Ejecución sin una instalación global
Siempre puedes invocar directamente el punto de entrada compilado:
```bash
# Print general CLI help and usage
node packages/cli/dist/index.js --help
# Print check command help (lists all methods, categories, and WAF vendors)
node packages/cli/dist/index.js check --help
# Discover detectable WAF vendors and payload categories (JSON for automation)
node packages/cli/dist/index.js list-wafs --json
node packages/cli/dist/index.js list-categories --json
```
#### Detección de WAF
Detecta el proveedor de WAF detrás de una URL objetivo:
```bash
node packages/cli/dist/index.js detect <url>
```
#### Auditoría de payloads de vulnerabilidad
Ejecutar una auditoría contra una URL objetivo:
```bash
# Default check (GET method, all payload categories)
node packages/cli/dist/index.js check https://example.com
# Custom check with specific methods, categories, and WAF evasion enabled
node packages/cli/dist/index.js check https://example.com -m GET,POST -c "SQL Injection,XSS" --auto-detect-waf --encoding-variations
```
#### Auditorías por lotes
Ejecuta auditorías por lotes para una lista de URL definidas en un archivo:
```bash
node packages/cli/dist/index.js batch targets.txt --concurrency 3
```
#### Generación de informes
Guarde los resultados de la auditoría en formato **SARIF**, **JUnit XML**, **HTML**, **Markdown**, **CSV** o **JSON**:
```bash
# Generate SARIF report for GitHub Code Scanning
node packages/cli/dist/index.js check https://example.com -o results.sarif
# Generate JUnit XML for CI test reporting (GitHub Actions, GitLab CI, Jenkins)
node packages/cli/dist/index.js check https://example.com -o results.xml
# Generate interactive HTML report
node packages/cli/dist/index.js check https://example.com -o report.html
# Generate Markdown summary for CI
node packages/cli/dist/index.js check https://example.com -o summary.md
```
> El formato del informe se deduce de la extensión del archivo de salida, o se establece explícitamente con `-f, --format` (`json`, `csv`, `html`, `sarif`, `markdown`, `junit`). Cada payload de ataque se convierte en un `<testcase>` de JUnit; los bypasses del WAF se reportan como `failure`s y los errores de transporte/servidor como `error`s, de modo que los ejecutores de CI los muestran directamente.
#### Integración CI/CD y umbrales de protección
Haga fallar las canalizaciones CI/CD cuando la tasa de protección esté por debajo del umbral requerido o cuando se detecten bypasses:
```bash
# Fail if WAF protection rate is below 95%
node packages/cli/dist/index.js check https://example.com --threshold 95 -q
# Fail immediately on any detected bypass
node packages/cli/dist/index.js check https://example.com --fail-on-bypass -q
```
#### 🔀 Diffing de regresión (escaneo vs escaneo)
La postura del WAF cambia con el tiempo: un proveedor publica una actualización de su conjunto de reglas gestionadas, una regla de CRS se desactiva, un cambio en el origen altera un veredicto. En lugar de volver a triar la lista completa de resultados en cada ejecución, compara con un informe JSON guardado previamente y aplica condiciones en CI únicamente sobre el *empeoramiento*. Un payload que estaba `blocked` en el informe de referencia y ya no está bloqueado cuenta como una regresión; un payload recién bloqueado cuenta como una mejora. La coincidencia se realiza por `(category, method, evasion technique, payload)`, y los errores de red / bloqueos del lado del origen se tratan como no concluyentes, de modo que nunca aparecen como falsas regresiones.
```bash
# Save a known-good baseline report
node packages/cli/dist/index.js check https://example.com -f json -o baseline.json -q
# Later: diff the current scan against it and print regressions/improvements
node packages/cli/dist/index.js check https://example.com --compare baseline.json -q
# Fail CI only when a previously-blocked payload is no longer blocked
node packages/cli/dist/index.js check https://example.com --compare baseline.json --fail-on-regression -q
```
#### 🛡️ Parcheo virtual y remediación automática
Genera automáticamente reglas de firewall listas para desplegar en las 11 plataformas compatibles (`cloudflare`, `aws`, `gcp`, `azure`, `modsecurity`, `nginx`, `haproxy`, `caddy`, `apache`, `envoy`, `k8s`, o `all`):
```bash
# Generate and save Cloudflare Terraform rules during audit
node packages/cli/dist/index.js check https://example.com --patch cloudflare --patch-output ./cloudflare-patch.tf
# Generate GCP Cloud Armor gcloud commands and Terraform
node packages/cli/dist/index.js check https://example.com --patch gcp --patch-output ./cloud-armor.sh
# Generate Azure WAF rules with simulation (Log) mode
node packages/cli/dist/index.js check https://example.com --patch azure --patch-action simulate --patch-output ./azure-rules.json
# Generate HAProxy ACLs for haproxy.cfg
node packages/cli/dist/index.js check https://example.com --patch haproxy --patch-output ./haproxy-patches.cfg
# Generate Caddyfile named matchers
node packages/cli/dist/index.js check https://example.com --patch caddy --patch-output ./patches.caddyfile
# Generate Apache mod_rewrite rules for .htaccess
node packages/cli/dist/index.js check https://example.com --patch apache --patch-output ./patches.htaccess
# Generate Kubernetes Ingress YAML manifests
node packages/cli/dist/index.js check https://example.com --patch k8s --patch-output ./ingress-patch.yaml
# Generate patches for all vendors from a saved JSON audit report file
node packages/cli/dist/index.js patch audit-report.json --waf all --output ./patches/
```
#### 🐳 Pruebas en entorno local con Docker y de staging (`--allow-local`)
Por defecto, `waf-checker` bloquea estrictamente los rangos de IP privadas (`127.0.0.1`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) para prevenir la falsificación de peticiones del lado del servidor (SSRF). Al probar tus propios contenedores Docker locales o servidores de staging, usa `--allow-local`:
```bash
# Audit a local OWASP ModSecurity Docker container and run reverse engineering
node packages/cli/dist/index.js check http://127.0.0.1:8088/ --allow-local --reverse
# Audit a local Caddy or HAProxy reverse proxy and generate patches
node packages/cli/dist/index.js check http://127.0.0.1:8089/ --allow-local --patch caddy
```
#### 🧪 Suite E2E automatizada con Docker en vivo (`npm run test:e2e`)
Ejecuta auditorías de integración de extremo a extremo contra contenedores Docker en vivo (ModSecurity CRS, Caddy, HAProxy, NGINX y Backend) con un solo comando:
```bash
npm run test:e2e
```
Consulta la [Guía completa de pruebas locales de WAF y validación E2E](https://github.com/sech0us3/waf-checker/blob/main/docs/LOCAL_WAF_TESTING.md) para ver los benchmarks completos, los diagramas de arquitectura y los pasos de reproducción manual.
---
## 🚀 GitHub Action (CI/CD)
Integra pruebas automatizadas de seguridad de WAF en tu flujo de trabajo de GitHub Actions:
```yaml
name: WAF Security Audit
on:
push:
branches: [ main ]
schedule:
- cron: '0 0 * * 1' # Weekly audit
jobs:
waf-audit:
runs-on: ubuntu-latest
permissions:
security-events: write # Required for SARIF upload
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run WAF Checker
uses: SecH0us3/waf-checker@main
with:
target-url: 'https://staging.example.com'
threshold: '95'
enhanced: 'true'
advanced: 'true'
sarif-output: 'waf-results.sarif'
html-output: 'waf-report.html'
- name: Upload SARIF to GitHub Security Tab
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'waf-results.sarif'
- name: Upload HTML Report Artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: waf-audit-report
path: waf-report.html
```
### 3. Versión de Docker
Puedes ejecutar la CLI usando Docker, ya sea descargando la imagen precompilada desde GitHub Container Registry o compilándola localmente.
#### Usando la imagen precompilada (recomendado)
La imagen de Docker precompilada está disponible en [GitHub Container Registry](https://github.com/SecH0us3/waf-checker/pkgs/container/waf-checker-cli) en `ghcr.io/sech0us3/waf-checker-cli`.
##### Descargar la imagen
```bash
docker pull ghcr.io/sech0us3/waf-checker-cli:latest
```
##### Mostrar ayuda
```bash
docker run --rm ghcr.io/sech0us3/waf-checker-cli:latest --help
```
##### Ejecutar una comprobación
```bash
docker run --rm -it ghcr.io/sech0us3/waf-checker-cli:latest check https://example.com
```
##### Ejecutar auditorías por lotes (montando un directorio local)
```bash
docker run --rm -it -v "$(pwd):/data" ghcr.io/sech0us3/waf-checker-cli:latest batch /data/targets.txt --concurrency 3
```
#### Compilación local
##### Compilar la imagen
```bash
docker build -t waf-checker-cli .
```
##### Mostrar ayuda
```bash
docker run --rm waf-checker-cli --help
```
##### Ejecutar una comprobación
```bash
docker run --rm -it waf-checker-cli check https://example.com
```
##### Ejecutar auditorías por lotes (montando un directorio local)
```bash
docker run --rm -it -v "$(pwd):/data" waf-checker-cli batch /data/targets.txt --concurrency 3
```
## 🔌 API e integración (para consumidores externos y fuzzers)
El Cloudflare Worker expone una API REST pública consumida por escáneres y fuzzers (incluido [swazz](https://github.com/SecH0us3/swazz)). La especificación completa de OpenAPI 3.1 está disponible en [`docs/openapi.yaml`](https://github.com/sech0us3/waf-checker/blob/main/docs/openapi.yaml).
### Resumen de endpoints
| Endpoint | Método | Descripción |
|---|---|---|
| `/api/waf-detect` | `GET` | Identifica el proveedor de WAF, la puntuación de confianza y los bypasses sugeridos. |
| `/api/check` | `GET`, `POST` | Sondea el objetivo con payloads de ataque. Admite paginación y filtrado por categoría. |
| `/api/virtual-patch` | `POST` | Genera reglas de remediación para Cloudflare, AWS, ModSec, NGINX, Caddy, HAProxy, Coraza. |
| `/api/reverse-engineer` | `GET`, `POST` | Realiza ingeniería inversa de las reglas de OWASP CRS, los umbrales de anomalía y los límites de cuerpo. |
| `/api/audit` | `GET`, `POST` | **Auditoría unificada**: ejecuta detección, comprobaciones de seguridad y parches virtuales, normalmente en una sola solicitud (véase Paginación de auditoría). |
### Características clave de integración
- **Envoltorio de paginación (`?envelope=1` o `?envelope=true`)**:
Envuelve los resultados en un envoltorio estructurado con metadatos de paginación:
```json
{
"results": [...],
"page": 0,
"pageSize": 50,
"total": 72,
"hasMore": true
}
```
*(Omita `?envelope=1` para recibir el array JSON simple predeterminado por compatibilidad con versiones anteriores).*
- **Paginación de auditoría (`/api/audit`)**:
Una auditoría devuelve todo en una sola respuesta (`hasMore: false`) a menos que su plan supere lo que permite el presupuesto de subconsultas de una solicitud de Cloudflare Worker (1658 elementos). Eso cubre ningún WAF detectado (513 elementos) y las variaciones de bypass de cada WAF hasta Sophos (1321); un objetivo protegido por Qrator (2441 elementos) se devuelve en dos páginas, al igual que cualquier auditoría en la que se pase un `pageSize` más pequeño. Las respuestas incluyen `page`, `pageSize`, `total`, `hasMore` y `detectedWAF` (`""` si no se encontró ninguno). Mientras `hasMore` sea true, solicite `page=<page + 1>&detectedWAF=<detectedWAF>`; devolver `detectedWAF` evita la redetección (`detection` es entonces `null`) y mantiene estables los límites de página. `patches` cubre los resultados de esa respuesta; para un único bundle repartido en varias páginas, haga `POST` de los `results` combinados a `/api/virtual-patch`.
- **Confianza normalizada (`/api/waf-detect`)**:
Proporciona `confidencePercent` (0–100) junto con `confidence` y `confidenceThreshold` sin procesar (`40`).
- **Veredicto por resultado y flags de bloqueo**:
Cada `AuditResultItem` incluye:
- `blocked: boolean` — Indica si el WAF intervino antes de llegar al origen.
- `verdict: 'blocked' | 'passed' | 'exposed'` — Resultado distinto que diferencia entre filtraciones (`exposed`) y brechas de cobertura (`passed`).
- `error: string | null` — Categoría de error explícita en caso de caída de red (p. ej. `'timeout'`, `'dns'`, `'connection_reset'`).
- **Rechazo de autoescaneo (HTTP 422)**:
Rechaza los autoescaneos accidentales dirigidos a la infraestructura del servicio con `{ "error": "self-scan refused", "code": "SELF_SCAN_REFUSED" }`.
---
## Pruebas
Para ejecutar la suite de pruebas de todo el workspace (utilizando Vitest):
```bash
npm test
```
---
Lee mi blog en [yoursec.substack.com](https://yoursec.substack.com/)