Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Herramientas/GitHubGitHub/j3ssie/dynast-bench
Escáneres de VulnerabilidadesEscáneres de Vulnerabilidades WebPruebas de Seguridad de APIsPruebas de PenetraciónAprendizaje y EducaciónRecursos CuradosLabs y Práctica
GitHubj3ssie/dynast-bench

dynast-bench

Un benchmark DAST de aplicaciones intencionalmente vulnerables con claves de respuesta de referencia para puntuar escáneres.

Ver Repositorio
8hace 18 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

DynAST-Bench

Un benchmark DAST de aplicaciones intencionalmente vulnerables con claves de respuesta de referencia (ground truth) para puntuar escáneres.

⚠️ Este repositorio contiene aplicaciones DELIBERADAMENTE INSEGURAS. Existen únicamente para evaluar herramientas de seguridad: escáneres DAST, motores SAST y agentes de seguridad LLM. Cada aplicación se vincula a 127.0.0.1, muestra un banner LLAMATIVO y no contiene datos reales. Nunca despliegue nada de esto en una red pública.

Un conjunto de 19 aplicaciones intencionalmente vulnerables, una por stack, cada una con una ground truth documentada y verificable por máquina. El objetivo es medir qué tan bien un escáner o agente (a) encuentra los bugs plantados, (b) ignora el código seguro de casi-acierto (near-miss) que está justo al lado, y (c) no alucina hallazgos en el gemelo parcheado.

Las aplicaciones de un vistazo

19 aplicaciones · 549 vulnerabilidades plantadas · 146 casi-aciertos · 546 PoCs ejecutables · 594 endpoints catalogados. Cada aplicación arranca en 127.0.0.1:13311, incluye un par gemelo vuln/+safe/ y una compilación --solo de imagen única. imprime esta tabla en vivo; imprime su catálogo de endpoints.

dynast-bench list
dynast-bench surface <app>
AppStackAlmacén de datosVulnsCasi-aciertoDocs
aspnetC# / ASP.NET Core Razor PagesSQL Server2812plan
fastapiPython / FastAPI + Jinja2Postgres265plan
ginGo / GinPostgres127readme
golangGo / chiPostgres264plan
graphqlNode / GraphQL 16 API-onlyPostgres316plan
jspJava / JSP + Servlets (Tomcat)Postgres286plan
laravelPHP 8.3 / Laravel 11 + BladeMySQL257plan

Sidecars adicionales por stack (Mailpit, MinIO, Redis, Jenkins, Prometheus, Ollama, …) se enumeran en Las aplicaciones más abajo.

Los documentos de diseño por stack viven en benchmark-plans/: comience allí para ver el catálogo completo de vulnerabilidades de cada aplicación. Este README es la guía operativa: cómo está organizado el repositorio y cómo ejecutar y puntuar una aplicación.

Clases de vulnerabilidades cubiertas

Cada bug plantado lleva un CWE y una categoría OWASP. Agrupados por clase: cada bug se cuenta una vez, bajo su CWE principal: los bugs plantados se desglosan aproximadamente como sigue (el rollup se regeneró por última vez con 480 bugs; los recuentos por aplicación anteriores están actualizados):

ClaseCWEsBugsApps
Exposición de datos sensibles (errores, logs, endpoints de depuración, copias de seguridad, código fuente)200, 209, 489, 524, 532, 538, 540, 5483916
Credenciales por defecto / hardcodeadas / filtradas321, 522, 798, 1104, 13923818
Autorización ausente o rota (BFLA, vertical + horizontal)269, 284, 285, 668, 862, 8633718
Cross-site scripting (reflejado · almacenado · DOM)792816
Bypass de autenticación · sesión débil · verificación JWT287, 288, 290, 306, 347, 384, 613, 614, 13852813
Inyección SQL (incl. de segundo orden, ORDER BY, NoSQL)89, 9432717
Conflictos de interpretación proxy/parser (confusión de rutas, confianza en cabeceras)345, 348, 349, 436, 441, 693, 697, 706, 8072710
SSRF (incl. ciego, cadenas de redirección, sinks solo internos)9182017
IDOR / BOLA (clave de objeto controlada por el usuario)6391917
Path traversal · LFI/RFI · zip slip22, 981916
Mass assignment / sobre-publicación · contaminación de prototipos915, 13211816
Fuerza bruta · falta de rate limiting · agotamiento de recursos307, 400, 406, 674, 7701711
Abuso de lógica de negocio, precios y cuotas625, 8401514
Inyección de comandos / argumentos del SO781412
Deserialización insegura (pickle · PHP · Java · YAML)470, 5021411

Por categoría OWASP (Top 10 2021 para las aplicaciones web, API Top 10 2023 donde la aplicación es solo API):

OWASPBugsOWASP APIBugs
A01 Broken Access Control118API8 Security Misconfiguration21
A03 Injection89API5 Broken Function Level Authorization6
A05 Security Misconfiguration72API1 Broken Object Level/Property Authorization4
A07 Identification & Authentication Failures65API2 Broken Authentication4
A04 Insecure Design34API7 Server Side Request Forgery4
A08 Software & Data Integrity Failures17API9 Improper Inventory Management3
A10 SSRF15API3 Broken Object Property Level Authorization2
A02 Cryptographic Failures15API4 Unrestricted Resource Consumption2
A09 Logging & Monitoring Failures4API6 Unrestricted Access to Sensitive Business Flows1
A06 Vulnerable & Outdated Components3API10 Unsafe Consumption of APIs1

Dos pistas no web se sitúan junto a estas: la aplicación network planta 32 hallazgos de host/puerto y de nivel de servicio para escáneres de red, y las dos aplicaciones LLM (llmchat, llmagent) plantan bugs de prompt-injection, abuso de herramientas y envenenamiento RAG puntuados en una pista separada de canal de inyección.

Cada bug también está etiquetado con una dificultad de detección (118 E, 68 E-M, 202 M, 61 M-H, 100 H), una distancia de taint (351 in-file, 83 cross-file, 87 cross-service, 28 config) y una alcanzabilidad (368 pre-auth, 181 user), de modo que el recall puede desglosarse a lo largo de cada uno de esos ejes en lugar de informarse como un único número. Los catálogos por aplicación viven en benchmark-plans/.

Estructura del repositorio```

dynast-bench/ ├── README.md # you are here - overview, safety, run/score guide ├── examples/ # ready-to-score findings/v1 + endpoints/v1 files ├── Makefile # top-level runner: list / run / verify / validate / solo any app ├── benchmark-plans/ # per-stack design docs (the vulnerability catalogs) ├── dynast-bench/ # the dynast-bench CLI + scorer (Bun/TS) └── vulnerable-apps/ # the 19 apps - each a separated, self-contained folder ├── _template/ # skeleton; copy it to start a new app ├── fastapi/ golang/ nextjs/ nestjs/ springboot/ └── rails/ wordpress/ php/ jsp/ aspnet/ ...

root@kitploit:~
## Ejecutar aplicaciones (CLI `dynast-bench`)

La CLI es la forma más sencilla de manejar el conjunto de pruebas: verifica el estado de los arranques, arbitra
los puertos compartidos y habla `--json` para que un arnés de escáner pueda consumirlo.
Requiere [Bun](https://bun.sh) 1.2+ y Docker.```bash
make install                             # compile the CLI + link it into ~/.bun/bin
                                         # (BIN_DIR=/somewhere/else to pick the dir)

dynast-bench list                        # every app: vulns, PoCs, near-misses, what's up
dynast-bench vulns nextjs                # the planted bugs as a checklist, one title each
                                         # (--full · --near · --ids for a coverage diff)
dynast-bench start nextjs                # build + boot, wait for health, print the URL
dynast-bench verify nextjs               # run the ground-truth PoCs (expect all exploitable)
dynast-bench validate nextjs             # twin loop: vuln all-exploitable → safe all-fixed
dynast-bench status                      # variant, mode, target, health
dynast-bench stop --all                  # stop everything
dynast-bench clean --all --images --yes  # reclaim containers, volumes, networks, images

dynast-bench start nextjs --variant safe # the patched twin (false-positive run)
dynast-bench start --count 5 --parallel  # 5 apps at once, one port each + a summary table
dynast-bench start --all --solo --parallel   # whole fleet, one image + port each
dynast-bench run nextjs -- my-scanner --url '$TARGET'   # start → scan → stop

Referencia completa: dynast-bench/README.md.

Puertos

Todo vive en un segmento tranquilo del rango efímero, para que el conjunto no pelee con la multitud habitual de 3000/8000/8080/5432 - y cada aplicación posee un puerto fijo, de modo que una URL siempre significa la misma aplicación, sola o en un lote de cinco:

rangoqué
13311–13339la aplicación bajo prueba - la URL a la que apuntas con un escáner, un puerto por aplicación en orden de list (aspnet 13311, fastapi 13312, … nextjs 13322)
13340–13484los sidecars de esa aplicación (mailpit, phpMyAdmin, Jenkins, Prometheus, …), 5 por cada una
13500–13599grupo de reubicación

dynast-bench list es el mapa. Si algo ya está escuchando en un puerto que una aplicación posee, dynast-bench start lo deja en paz y publica ese servicio desde el grupo de reubicación en su lugar, y luego imprime (y reporta con --json) la URL real. Nada se vincula jamás más allá de 127.0.0.1. dynast-bench doctor muestra qué puertos de aplicaciones están libres; los objetivos de make no reubican y publican los valores predeterminados de compose (13311+) una aplicación a la vez, respetando DYNAST_PORT=<n>; --port N lo fija.

Ejecutar aplicaciones (Makefile de nivel superior)

Los Makefiles siguen siendo el contrato de bajo nivel y funcionan de forma independiente:```bash make list # show all apps (a [solo] tag = has a single-image build) make run APP=nextjs # start via compose (app + datastores) make verify APP=nextjs # run its ground-truth PoCs (expect all exploitable) make validate APP=nextjs # full twin loop: vuln all-pass -> safe all-fixed make down APP=nextjs # stop it make solo APP=nextjs # run as ONE self-contained image - no compose needed make solo-down APP=nextjs # stop the standalone image

shorthands: make run-nextjs make validate-nextjs

root@kitploit:~
Dos formas de ejecutar cada aplicación:
- **Compose** (`make run`) - la topología multi-servicio canónica que los
  objetivos de ground truth (app + Postgres/Redis/etc. como contenedores separados).
- **Standalone** (`make solo`) - una imagen autocontenida por aplicación
  (`vuln/Dockerfile.standalone`) con los almacenes de datos + un sumidero SSRF interno
  integrado, de modo que `docker build` + `docker run` funcionan sin compose. El comportamiento
  y los PoCs son idénticos (los nombres de los servicios de compose están aliasados a `127.0.0.1`).

La raíz se mantiene deliberadamente pequeña: este README, la guía de diseño, las herramientas
compartidas y las aplicaciones. Todo lo operativo para una aplicación determinada está dentro de la
carpeta propia de esa aplicación.

## Anatomía por aplicación

Cada aplicación bajo `vulnerable-apps/` tiene la misma estructura:```
vulnerable-apps/<stack>/
├── README.md            # LOUD banner + run notes
├── Makefile             # up · reset · safe · verify · score · diff  (uniform interface)
├── vuln/                # the vulnerable variant - this is what you scan by default
│   ├── docker-compose.yml   # independent; binds 127.0.0.1 only
│   ├── app/                 # application source; the planted bugs live here
│   └── db/seed.sql          # seed incl. a cross-tenant user + a weak default cred
├── safe/                # the patched twin - same app, every planted bug fixed
│   ├── docker-compose.yml
│   ├── app/
│   └── db/seed.sql
└── ground-truth/        # the answer key - see "Ground truth" below
    ├── VULNERABILITIES.yaml  # every planted bug
    ├── SURFACE.yaml          # every endpoint the app exposes
    ├── verify/          # one runnable PoC per bug
    └── expected/        # optional golden normalized findings

El gemelo vulnerable/seguro

Cada aplicación incluye dos carpetas de variantes separadas en lugar de ramas de git o archivos de parche:

  • vuln/ - la aplicación con cada error plantado. El objetivo predeterminado; a lo que apunta un escáner.
  • safe/ - la misma aplicación con cada error plantado corregido y nada más cambiado (consultas parametrizadas, salida escapada, autorización añadida, deserializadores seguros, …).

diff -ru vulnerable-apps/<stack>/vuln vulnerable-apps/<stack>/safe es la verdad absoluta. Debe tocar exactamente las líneas nombradas en ground-truth/VULNERABILITIES.yaml y nada más. Escanear la variante safe/ mide la tasa de falsos positivos de una herramienta: cada hallazgo allí es una falsa alarma, porque el gemelo está limpio por construcción.

Debido a que el contexto de compilación de Docker de cada variante es su propia carpeta (vuln/ o safe/), el ground-truth/ de la aplicación queda fuera de cada contexto de compilación y no puede integrarse en una imagen - la clave de respuestas no puede filtrarse a la aplicación en ejecución, por construcción.

Verdad absoluta (ground-truth/)

Dos claves de respuestas, porque hay dos preguntas. VULNERABILITIES.yaml indica qué está mal en la aplicación; SURFACE.yaml indica qué existe en absoluto.

VULNERABILITIES.yaml registra una entrada por error plantado:```yaml

  • id: SQLI-001 variant_paths: # same relative path in both variants vuln: vuln/app/routes/search.py safe: safe/app/routes/search.py symbol: search_posts route: "GET /posts/search?q=" cwe: CWE-89 owasp: "A03:2021-Injection" severity: high # info | low | medium | high | critical difficulty: E # E | E-M | M | M-H | H (detection difficulty) taint: in-file # in-file | cross-file | cross-service reachability: pre-auth # pre-auth | user | admin near_miss: SAFE-SQLI-001 # id of the safe twin planted nearby match: # machine anchors for the scorer (generated) http: { method: GET, path: "/posts/search", params: [q] } file: { path: vuln/app/routes/search.py, symbol: search_posts, lines: [18, 24] } markers: [GLOBEX-CONFIDENTIAL-MARKER-7f3a] poc: ground-truth/verify/sqli_001.sh
root@kitploit:~
`SURFACE.yaml` registra una entrada por **operación que expone la aplicación**, tanto vulnerable como benigna: es el denominador para la [cobertura de endpoints](#endpoint-coverage):```yaml
operations:
  - id: posts.search
    kind: http                 # http | graphql | ws | llm | net
    method: GET
    path: /api/posts/search
    params: [q]
    discovery: js-runtime      # same crawl tiers as the answer key
    reachability: user
    vulns: [SQLI-001]          # omit when the operation is benign

  - id: graphql.mutation.update-post
    kind: graphql              # the op BEHIND POST /graphql, which is its own entry
    op: updatePost
    graphql_kind: mutation
    via: graphql.transport
    discovery: static-html

Las operaciones benignas están ahí a propósito: un catálogo solo con las rutas vulnerables mediría la cobertura de la clave de respuestas, no la de la app.

verify/ contiene un PoC ejecutable por cada bug: termina con 0 contra vuln/ y distinto de cero contra safe/. Esa es la definición ejecutable de "el bug es real (y de hecho está corregido en su gemelo)".

El runner compartido (dynast-bench/tools/poc-runner.sh) añade un tercer resultado que el código de salida no puede transmitir por sí solo: el harness no pudo ejecutarse. Si apuntas el conjunto a un puerto donde nada está escuchando, una buena mitad de los PoCs de cualquier app termina con 1, indistinguible de una corrección genuina. Por eso el runner hace una comprobación de salud del objetivo antes de creer en un rechazo, aplica un plazo por PoC y falla ambas ramas ante un timeout, una herramienta ausente o un objetivo que dejó de responder. "El conjunto no pudo ejecutarse" nunca se registra como "la vulnerabilidad está corregida".

Herramientas compartidas (dynast-bench/, Bun/TypeScript)

Un único toolchain, usado por todas las apps, para que los resultados entre stacks sean comparables:

  • dynast-bench.ts - la CLI: iniciar/detener/reiniciar/limpiar, compuerta de salud, arbitraje de puertos, verificación de PoCs, puntuación, --json para harnesses.
  • src/schema/ - tipos y validadores para los dos formatos de informe (findings/v1, endpoints/v1) y las dos claves de respuestas (VULNERABILITIES.yaml, SURFACE.yaml), la tabla de familias CWE usada para el crédito parcial, y los normalizadores de ruta/route/operación por los que pasan ambos lados de una comparación.
  • src/normalize/ - adaptadores que convierten la salida cruda de escáneres (OWASP ZAP, SARIF de Semgrep/CodeQL/Snyk, nuclei, Burp XML, nmap XML) a ese formato. El formato se detecta automáticamente, así que score acepta salida nativa directamente.
  • src/scorer/ - compara los hallazgos con la clave de respuestas y emite precisión / recall / F1, recall por dificultad / severidad / alcanzabilidad / taint / CWE, una puntuación de discriminación sobre los casi-aciertos, y una proporción de duplicados (ruido). Junto a ello, una pista de cobertura de endpoints califica cuánto de la app alcanzó realmente una ejecución y divide cada fallo en "nunca encontró el endpoint" vs "lo encontró, pero falló el bug".``` dynast-bench verify # run the app's ground-truth PoCs dynast-bench score findings.json # findings → P/R/F1 + per-dimension recall dynast-bench coverage endpoints.json # endpoint discovery → how much was reached dynast-bench surface # the operation checklist a crawl is graded on dynast-bench diff # the vuln↔safe delta vs the answer key dynast-bench check --all # CI gate: schema · anchors · diff scope · binds
root@kitploit:~
[`examples/`](https://github.com/j3ssie/dynast-bench/blob/main/examples) contiene archivos que puedes puntuar de inmediato: una ejecución de hallazgos, una ejecución de falsos positivos, tres trazas de endpoints y dos plantillas en blanco, cada una documentada con los números que produce:```bash
dynast-bench score    nextjs examples/findings.json --safe examples/findings-safe.json
dynast-bench coverage nextjs examples/endpoints.json --findings examples/findings.json

Referencia completa: el esquema de hallazgos, los niveles de coincidencia, cada métrica: dynast-bench/README.md.

Interfaz Makefile uniforme (idéntica en cada aplicación)```

make up # docker compose up the vuln/ variant (127.0.0.1 only), wait for health make reset # down -v && up → fresh, byte-identical state make safe # bring up the safe/ variant instead (for false-positive runs) make verify # run every ground-truth PoC; expect all PASS against vuln/ make score FINDINGS=f.json # grade a scanner's findings → P/R/F1 make diff # the vuln↔safe delta, cross-checked against the answer key make check # CI gate: schema · anchors · diff scope · PoCs · 127.0.0.1 binds

root@kitploit:~
## Las aplicaciones

| App        | Stack                          | DB         | Servicios adicionales | Documento de diseño |
|------------|--------------------------------|------------|----------------------|------------|
| fastapi    | Python / FastAPI + Jinja2      | Postgres   | MinIO, Mailpit       | [fastapi.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/fastapi.md) |
| golang     | Go / chi                       | Postgres   | Prometheus, Grafana  | [golang.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/golang.md) |
| gin        | Go / Gin                       | Postgres   | chromium, ImageMagick (en la imagen) | [README](https://github.com/j3ssie/dynast-bench/blob/main/vulnerable-apps/gin/README.md) |
| nextjs     | Node / Next.js 15              | Postgres   | Redis, Mailpit       | [nextjs.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/nextjs.md) |
| nestjs     | Node / NestJS + Handlebars     | Postgres   | Redis, nginx         | [nestjs.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/nestjs.md) |
| springboot | Java / Spring Boot + Thymeleaf | Postgres   | Jenkins, Prometheus  | [springboot.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/springboot.md) |
| rails      | Ruby / Rails 7.2               | Postgres   | MinIO, nginx         | [rails.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/rails.md) |
| wordpress  | PHP / WordPress + plugin       | MySQL      | nginx, Mailpit       | [wordpress.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/wordpress.md) |
| php        | PHP / LAMP procedural          | MySQL      | phpMyAdmin, Mailpit  | [php.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/php.md) |
| jsp        | Java / JSP + Servlets (Tomcat) | Postgres   | Mailpit              | [jsp.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/jsp.md) |
| aspnet     | C# / ASP.NET Core Razor Pages  | SQL Server | Mailpit              | [aspnet.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/aspnet.md) |

Más tres aplicaciones **solo API** (GraphQL, WebSocket, Swagger/OpenAPI), una
flota de **rango de red** para escáneres de host/puertos, y dos aplicaciones **LLM**:

| App        | Stack                                       | DB                | Servicios adicionales                       | Documento de diseño |
|------------|---------------------------------------------|-------------------|--------------------------------------|------------|
| llmchat    | Python / FastAPI + LangChain (chatbot RAG)  | Postgres+pgvector | Redis, Ollama, svc interno          | [llmchat.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/llmchat.md) |
| llmagent   | Node / Fastify + Vercel AI SDK + MCP (agente)| Postgres          | Redis, Ollama, partner-MCP, svc interno | [llmagent.md](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/llmagent.md) |

Ambas aplicaciones LLM ejecutan un **modelo local** mediante un contenedor Ollama
de solo acceso interno (`gemma3:1b` para chat, `qwen2.5:1.5b` para llamadas a herramientas) - sin clave API, sin salida de red,
sin coste por ejecución - e incluyen un backend con script `LLM_BACKEND=stub` para que
los PoCs de referencia sigan siendo deterministas frente a un modelo estocástico.

Consulta [`benchmark-plans/README.md`](https://github.com/j3ssie/dynast-bench/blob/main/benchmark-plans/README.md) para el
modelo de dominio compartido, la matriz de cobertura OWASP-Top-10 y los
principios de diseño del benchmark (casi aciertos, distancia de taint, errores solo de lógica).

## Primeros pasos```bash
make install                           # once: puts `dynast-bench` on your PATH
dynast-bench doctor                    # docker reachable? which ports are taken?

dynast-bench start fastapi             # boots the vuln/ variant, waits for health
dynast-bench verify fastapi            # sanity-check: every planted bug's PoC PASSes

# ...point your scanner/agent at $(dynast-bench target fastapi), collect findings.json...

dynast-bench start fastapi --variant safe   # patched twin → measures false positives
dynast-bench reset fastapi                  # restore fresh, re-seeded state
dynast-bench clean --all --yes              # give the disk back

O bien ejecuta una aplicación directamente con su Makefile:```bash cd vulnerable-apps/fastapi make up # vuln/ variant on 127.0.0.1 make verify # every planted bug's PoC PASSes make safe # the patched twin make reset # fresh state

root@kitploit:~
## Estado

- **19 aplicaciones incluyen una clave de respuestas completa**: 549 vulnerabilidades plantadas, 146
  casi-aciertos, 546 PoCs y un `Dockerfile.standalone` cada una (`--solo`).
  `dynast-bench list` imprime la tabla en vivo.
- **`nextjs` es la implementación de referencia**: construida y validada de extremo a extremo
  (35 vulns + 15 casi-aciertos). `make validate APP=nextjs` demuestra que cada PoC
  es explotable en `vuln/` y está corregido en `safe/`; `make solo APP=nextjs` lo ejecuta desde
  una sola imagen. Copia sus patrones.
- **CLI `dynast-bench`: construida**: ejecuta, verifica, puntúa y limpia cualquier aplicación, en
  modo compose o de imagen única, con `--json` para harnesses.
- **El puntuador: construido** (`dynast-bench/src/`): salida del escáner → hallazgos normalizados
  → precisión/recall/F1, recall por dificultad, una puntuación de discriminación sobre los
  casi-aciertos, y pistas separadas de descubrimiento (red) y canal de inyección (LLM).
- **Cobertura de endpoints: construida**: un `SURFACE.yaml` por aplicación (~600 operaciones en
  toda la flota) que califica cuánto de la aplicación alcanzó realmente una ejecución, y divide
  cada fallo en "nunca encontró el endpoint" vs "lo encontró, pero falló el bug".
- Las invariantes por aplicación sobre las 19 claves de respuestas y los catálogos de superficie se ejecutan en
  `make test`; `dynast-bench check --all` es la puerta de CI.

## Puntuando una herramienta```bash
dynast-bench start nextjs --json | jq -r .target        # boot, get the URL
zap-baseline.py -t http://127.0.0.1:13311 -J zap.json   # scan
dynast-bench score nextjs zap.json --full               # grade it

# measure false positives properly: scan the patched twin too
dynast-bench start nextjs --variant safe
my-scanner --url http://127.0.0.1:13311 --out safe.json
dynast-bench score nextjs zap.json --safe safe.json

score lee un archivo findings/v1 o la salida nativa de ZAP / SARIF / nuclei / Burp / nmap — el formato se detecta automáticamente. Comienza desde examples/ si estás integrando una herramienta: examples/template-findings.json es un esqueleto en blanco con todos los campos, y examples/findings.json es un archivo funcional que puedes puntuar ahora mismo.

El descubrimiento de endpoints se evalúa por separado, contra el SURFACE.yaml de cada aplicación:```bash dynast-bench coverage nextjs endpoints.json --findings findings.json

root@kitploit:~
Eso es lo que separa un **fallo de descubrimiento** (nunca llegó al endpoint - arregla el
crawler) de un **fallo de análisis** (llegó a él, no lo reportó - arregla el escáner).
Consulta [`dynast-bench/README.md`](https://github.com/j3ssie/dynast-bench/blob/main/dynast-bench/README.md#scoring) para ver el esquema, los
niveles de coincidencia y cada métrica.

### Lectura del informe (`Leg │ Precision │ Recall │ F1`)

Una **leg** es una ejecución de escaneo contra un estado objetivo:

| Leg | Qué es |
|---|---|
| `blackbox` | sin credenciales - la vista del atacante no autenticado |
| `credentialed` | el mismo objetivo con los inicios de sesión sembrados inyectados, de modo que la superficie autenticada (IDOR, escalada de privilegios) es alcanzable |
| `safe-twin` | el gemelo parcheado (`--safe`), una línea base de falsos positivos - idealmente no encuentra nada |

Las tres se ejecutan en `0.0`–`1.0`, y para las tres **más alto es mejor** (`1.0` es perfecto):

| Métrica | Fórmula | Mejor | Se lee como |
|---|---|---|---|
| **Precision** | `TP / (TP + FP)` | ↑ más alto | de todo lo reportado, cuánto era real. `0.38` = ~38% de los hallazgos eran genuinos, el resto ruido. Alto = pocas falsas alarmas. |
| **Recall** | `TP / (TP + FN)` | ↑ más alto | de los bugs realmente plantados, cuántos se encontraron. `0.73` = 8 de 11. Alto = pocos fallos. |
| **F1** | `2 × P × R / (P + R)` | ↑ más alto | media armónica de ambos - el número principal de "calidad general". Solo es alto cuando ambos lo son, por lo que penaliza ser ruidoso *y* fallar bugs. |

La única inversión: en la **leg `safe-twin` no hay nada real que encontrar**, así que
cada hallazgo allí es una falsa alarma - menos es mejor, y un informe vacío es
la puntuación perfecta.

## Cobertura de endpoints

El recall te dice cuántos bugs encontró una herramienta. No puede decirte **por qué** falló
el resto - y las dos razones necesitan correcciones opuestas:

| Fallo | Significado | Qué arreglar |
|---|---|---|
| **fallo de descubrimiento** | nunca llegó al endpoint que contiene el bug | el crawler |
| **fallo de análisis** | llegó al endpoint, no reportó el bug | el análisis |

Distinguirlos requiere una segunda entrada: los endpoints que tu herramienta dice haber encontrado.
Eso es `endpoints/v1`, puntuado contra el `SURFACE.yaml` de cada app.```bash
dynast-bench surface  nextjs                       # the checklist a crawl is graded on
dynast-bench coverage nextjs endpoints.json        # how much did it reach?
dynast-bench coverage nextjs endpoints.json --findings findings.json   # ...and why not the rest
dynast-bench score    nextjs findings.json --endpoints endpoints.json  # both in one report

Un rastreador que lee HTML y ejecuta JS pero nunca completa un flujo de varios pasos:``` operations 62.5% 25 of 40 detection 25.0% of the bugs on operations it reached misses: 11 never reached the operation · 18 reached it and did not report

static-html 6/6 100.0% js-static 5/5 100.0% js-runtime 11/19 57.9% interaction 3/5 60.0% flow 0/5 0.0%

root@kitploit:~
El desglose por niveles es la parte útil: 100% en `static-html` y 0% en `flow` es
un problema de descubrimiento, no un problema del escáner, y ambos se leen de forma
idéntica en un único número de recall.

Dos reglas mantienen honesto el número:

- **El transporte no es la operación.** Un `POST /graphql` no ejercita las 25
  operaciones GraphQL que hay detrás; un handshake de WebSocket no ejercita sus
  eventos; un `POST /api/runs` no ejercita las herramientas de un agente. Alcanzar
  una URL y ejercitar lo que vive allí se puntúan por separado.
- **La telemetría ausente no produce ningún track en absoluto**, nunca `0%`. "No
  medimos esto" y "no alcanzó nada" son afirmaciones opuestas sobre una herramienta.

Los endpoints reportados que no coinciden con nada cuestan precisión pero nunca
reducen la cobertura, así que rociar una wordlist no es una forma de puntuar más
alto. Modelo completo:
[`dynast-bench/README.md#endpoint-coverage`](https://github.com/j3ssie/dynast-bench/blob/main/dynast-bench/README.md#endpoint-coverage).

## Licencia

`dynast-bench` está hecho con ♥ por [@j3ssie](https://github.com/j3ssie) para
evaluar **Vigolium** y **Gimora** (un agente autónomo de seguridad ofensiva), y se
publica bajo la [licencia MIT](https://github.com/j3ssie/dynast-bench/blob/main/LICENSE).
Descargar herramienta
llmagentNode / Fastify + AI SDK + MCPPostgres298plan
llmchatPython / FastAPI + LangChain RAGPostgres+pgvector309plan
nestjsNode / NestJS + HandlebarsPostgres236plan
networkRango de red multi-host simuladoflota mixta325plan
nextjsNode / Next.js 15 (implementación de referencia)Postgres3515plan
phpPHP / LAMP proceduralMySQL215plan
railsRuby / Rails 7.2Postgres266plan
springbootJava / Spring Boot + ThymeleafPostgres304plan
swaggerOpenAPI / Swagger UI + carga de especificacionesPostgres195plan
websocketNode 22 / ws + Socket.IO en tiempo realPostgres286plan
weirdproxynginx + Apache + Traefik sobre un único origenninguno164plan
wordpressPHP / WordPress + plugin personalizadoMySQL286plan
Configuración incorrecta de CORS9421414
Condiciones de carrera / TOCTOU3621414
Open redirect6011414
Enumeración de usuarios y recursos (discrepancia observable en la respuesta)204, 5981312
Inyección de código · SSTI · lenguaje de expresiones94, 917, 1059, 13361110
Criptografía y aleatoriedad débiles · transporte en claro295, 319, 327, 330, 338116
Fallos de restablecimiento de contraseña y recuperación de cuenta184, 64099
Subida de archivos sin restricciones / insegura43499
CSRF (incl. secuestro de WebSocket entre sitios)35288
Prompt injection y abuso de herramientas LLM (directo · indirecto · RAG)142772
XXE / entidad externa XML61155
Cadena de suministro e integridad (actualizaciones sin firmar, dependencias vulnerables)494, 103522
Exposición de red insegura (binding, configuración incorrecta del servicio)132721
Registro insuficiente / inyección en logs11711