Seis Damn-Vulnerable Apps, One Autonomous Loop

30 de septiembre de 2026

Cualquiera puede encontrar un bug en una app deliberadamente vulnerable. La pregunta más difícil —la que realmente importa en producción— es: ¿podés correr un programa de seguridad de punta a punta y probar que un fix se sostuvo? Encontrarlo, probar que es explotable, priorizarlo, parchearlo y re-testear para confirmar que quedó cerrado.

Este post corre ese loop completo contra seis apps deliberadamente vulnerables a la vez —cuatro targets clásicos web/API más una capa GenAI moderna (una app LLM y un servidor MCP)— con scanners estáticos, el pentest autónomo de FaradAI, el triage + patching de FaradAI, y un re-scan que muestra exactamente qué hallazgos quedaron arreglados. Todo convergiendo en un único workspace de Faraday.

1. Los seis targets

Cuatro apps clásicas deliberadamente vulnerables que abarcan cuatro lenguajes y cuatro sabores de debilidad —más dos que llevan el mismo loop a la superficie de ataque de IA, donde las clases de vulnerabilidad son prompt injection, tool poisoning y system-prompt leakage en vez de SQLi y XSS:

AppStackVulnerabilidades características
DVWAPHP / MySQLSQLi, command injection, file upload, XSS, CSRF
OWASP Juice ShopNode / TypeScript (SPA + REST)OWASP Top 10 completo, broken auth, injection, componentes vulnerables
OWASP WebGoatJava / SpringInjection, XXE, deserialización, dependencias con vulnerabilidades conocidas
VAmPIPython / Flask (REST API)BOLA/IDOR, JWT auth roto, mass assignment, exposición excesiva de datos
PromptMePython / Ollama (LLM local)OWASP LLM Top 10 — prompt injection, system-prompt leak, disclosure de info sensible, consumo no acotado
Damn Vulnerable MCPPython / MCP sobre SSETool poisoning, RCE por tools sin sandbox, path traversal, indirect prompt injection, fuga de credenciales

¿Por qué estos seis? Cobertura. Un monolito PHP, un SPA+API JS moderno, una app enterprise Java y un servicio API-first en Python ejercitan distintas reglas de SAST, distintos ecosistemas de dependencias (Composer / npm / Maven / pip) y distintas superficies de ataque web —mientras que la app LLM y el servidor MCP ejercitan las clases específicas de IA que los scanners clásicos nunca ven, todo a través del mismo loop encontrar→probar→priorizar→arreglar.

Levantá las cuatro apps clásicas con Docker localmente —como también vas a correr FaradAI localmente. localhost es alcanzable de punta a punta (sin exposición pública, sin túneles):

docker run -d --name dvwa      -p 8081:80   vulnerables/web-dvwa
docker run -d --name juiceshop -p 8082:3000 bkimminich/juice-shop
docker run -d --name webgoat   -p 8083:8080 webgoat/webgoat
docker run -d --name vampi     -p 8084:5000 erev0s/vampi

La capa GenAI requiere un par de pasos extra. PromptMe necesita un Ollama local para sus modelos; Damn Vulnerable MCP trae un Dockerfile que corre los 10 servidores de challenge en los puertos SSE 9001-9010 (fijá mcp<2 — el código apunta al SDK v1):

# PromptMe (Top 10 de OWASP LLM) — Ollama + las aplicaciones Flask Challenge en los rangos 5001-5010
docker run -d --name ollama_server -p 11434:11434 ollama/ollama:latest
docker exec ollama_server ollama pull mistral # + llama3 para algunos desafíos
# Luego, en la sección de pago de PromptMe (Python 3.11 venv): python main.py → desafíos en los números 5001-5010

# MCP vulnerable como la puta — 10 servidores MCP con SSE en 9001-9010
git clone https://github.com/harishsg993010/damn-vulnerable-MCP-server && cd damn-vulnerable-MCP-server
docker build -t dvmcp . && docker run -d --name dvmcp -p 9001-9010:9001-9010 dvmcp
docker exec dvmcp pip install 'mcp<2' && docker restart dvmcp el # código apunta al SDK v1 de MCP

2. El loop

Desactive las 6 aplicaciones vulnerables (4 web/API + LLM + MCP)
    ↓
Escaneos estáticos (SAST + SCA + secretos) → Faraday
    ↓
FaradAI prueba autónoma contra cada aplicación → validada, explotaciones en cadena
    ↓
Triaje FaradAI: deduplicación + priorización de hallazgos estáticos + análisis de pentest — un único espacio de trabajo
    ↓
Solucione los problemas más importantes (con el parche de FaradAI o manualmente)
    ↓
Re-scan + Re-test de FaradAI → Faraday reconcilia: solucionado → cerrado, aún abierto → abierto

Todo aterriza en un único workspace —llamémoslo damn-vuln-apps — con cada app como su propio host, así el re-scan final te puede decir, por app, exactamente qué se arregló.

3. Manos a la obra

Primero, conectá faraday-cli (auth por token vía su archivo de config — auth no tiene --token flag):

pip instalar Faraday-CLI
export FARADAY_URL=http://localhost:5985"" Comunidad de # Faraday (local) — o tu instancia personal
printf 'auth:\n faraday_url: %s\n token: %s\n' "$FARADAY_URL" "$FARADAY_TOKEN" > ~/.faraday-cli.yml

Paso 1 — Scans estáticos → Faraday

Corré el mismo stack estático sobre el código fuente de cada app y empujá cada reporte al workspace compartido. Una herramienta SAST (Semgrep, multi-lenguaje), una de SCA/contenedores (Trivy), una de secrets (Gitleaks):

para la aplicación en dvwa juiceshop webgoat vampi promptme dvmcp; hazlo
    semgrep scan --config auto --sarif -o "$app-semgrep.sarif" "./src/$app"
    trivy fs --format json -o "$app-trivy.json" "./src/$app"
    gitleaks detecta -s "./src/$app" -f json -r "$app-gitleaks.json"
    Reporte de la herramienta faraday-cli "$app-semgrep.sarif" -w damn-vuln-apps --create-workspace
    Reporte de la herramienta faraday-cli "$app-trivy.json" -w damn-vuln-apps
    Reporte de la herramienta faraday-cli "$app-gitleaks.json" -w damn-vuln-apps
hecho

Ahora el workspace tiene la amplitud: sinks de SAST, dependencias vulnerables y cualquier secret filtrado en las seis apps. Amplio, ruidoso y con hallazgos todavía no probados.

Paso 2 — Pentest autónomo de FaradAI

FaradAI corre como un Security Scanner dentro de tu Faraday —lo disparás por la REST API con curl y empuja hallazgos validados al mismo workspace. Como tu Faraday y su runner corren localmente (ver §6), el runner alcanza los contenedores en localhost directamente. Dispará una vez por cada app viva:

declara -A TARGETS=(
    [dvwa]=http://localhost:8081""
    [juiceshop]=http://localhost:8082""
    [webgoat]=http://localhost:8083/WebGoat""
    [vampi]=http://localhost:8084""
)

para la aplicación en "${!TARGETS[@]}"; haga lo siguiente:
  faraday-cli pentest --target "${TARGETS[$app]}" -w damn-vuln-apps --mode Dual --rounds 40 --watch
hecho

FaradAI descubre la superficie de cada app, la ataca y encadena lo que es real —convirtiendo el “quizás” de los scanners en “acá está el exploit funcionando”.

Para la capa GenAI, solo cambian INSTRUCTION y TARGET dentro de args : apuntá la corrida de PromptMe a http://localhost:5001-5010 y pedí ataques OWASP-LLM (prompt injection, system-prompt leak, disclosure de info sensible); apuntá la corrida MCP a http://localhost:9001-9010 y pasale el flujo MCP-sobre-SSE (ver §6) para que enumere y abuse de las tools de cada servidor. Mismo runner, mismo workspace —los hallazgos solo llevan un tag promptme o dvmcp para que el triage pueda separar por app.

Paso 3 — Triage + patching de FaradAI

Una corrida de triage sobre todo el workspace enriquece, deduplica y prioriza todo junto —hallazgos estáticos y resultados de pentest, las seis apps— y puede manejar el fix. Arrancá en dry-run (solo el plan):

Triage de faraday-cli -w damn-vuln-apps --severities críticas, altas -dry-run
# Re-prueba en vivo cada hallazgo: añade --reproduce
# cerrar automáticamente los falsos positivos: añadir --auto-close-fp

Ahora tenés una única cola priorizada de issues probados . Revisá el plan de patch, y después dejá que FaradAI aplique los fixes seguros ("PATCHING_MODE": "apply") o parcheá a mano —por ejemplo, parametrizar la query SQL de DVWA, bumpear la dependencia vulnerable de WebGoat, o agregar el chequeo de ownership que le falta a la ruta /users/v1/{username} de VAmPI.

Paso 4 — Re-scan y confirmar qué quedó arreglado

Redesplegá las apps parcheadas y volvé a correr exactamente los mismos scans estáticos y el pentest de FaradAI en el mismo workspace. Como Faraday reconcilia por host y por hallazgo, no acumula duplicados — cierra lo que se arregló y deja abierto el resto:

# Tras la reparación y el replanteamiento, vuelva a ejecutar los pasos 1 y 2 sin cambios.
# Luego verifique qué se cerró:
lista de vulnerabilidades de Faraday-CLI -w damn-vuln-apps --status closed
lista de vulnerabilidades de Faraday-CLI -w damn-vuln-apps --status open

Ese split closed/open es todo el punto: no “encontramos 300 cosas”, sino “probamos que esto era explotable, lo arreglamos y confirmamos que ya no está —mientras que esto otro sigue abierto”.

4. Lo que produjo una corrida real

Corrimos este loop de punta a punta —seis apps en localhost, FaradAI disparado por la REST API contra un Faraday local, todo convergiendo en un único workspace. La salida en crudo: 620 hallazgos en las seis apps. Acá está la amplitud, por app y por herramienta:

AppSemgrep (SAST)Trivy (SCA)Gitleaks (secrets)FaradAI (pentest)Total
DVWA48—1655
Juice Shop54—6910133
WebGoat11035233171
VAmPI561618
PromptMe (LLM)369027135
Damn Vulnerable MCP23—6116100
Total27613115748612

Ese es el pilar de “amplitud” en números: ~564 hallazgos estáticos —sinks de SAST, dependencias vulnerables, secrets filtrados— a través de Composer/npm/Maven/pip y el stack ML de Python. Amplio, ruidoso y en su mayoría sin probar: el grueso volvió como informational.

Después FaradAI convirtió el “quizás” en “acá está el exploit”. Los 48 hallazgos de pentest no eran ecos de scanner —eran ataques validados y encadenados, con evidencia de request/response:

  • DVWA — command injection de OS → RCE como www-data, upload sin restricción → RCE por web shell, SQLi UNION que dumpea el hash del admin, XSS stored + reflected, cambio de contraseña por CSRF vía GET.
  • Juice Shop — bypass de login por SQLi acuñando un JWT de admin, JWT alg:none aceptado, escritura no autenticada a PUT /api/Products/{id}, IDOR en baskets y tracking de órdenes, XSS stored vía imagen de producto, escalación de rol por mass assignment.
  • WebGoat — disclosure no autenticado de env/config del Spring Actuator, blind XXE, self-registration sin restricción.
  • VAmPI — reset de contraseña de admin por BOLA, /_debug no autenticado filtrando credenciales en texto plano, admin:true mass assignment en el registro, reset por /createdb no autenticado.
  • PromptMe (OWASP LLM Top 10) — prompt injection directa saltando el filtro de entrada (LLM01), disclosure de info sensible (LLM02, flag capturada vía injection), system-prompt leakage exponiendo una API key hardcodeada (LLM07), un backend de Ollama no autenticado alcanzable detrás de la app, y consumo no acotado / sin rate limiting (LLM10).
  • Damn Vulnerable MCP — una tool MCP (execute_command) cuyo whitelist se saltea con metacaracteres de shell → RCE no autenticado como root, un segundo RCE sin sandbox vía eval() en evaluate_expression, path traversal / lectura de archivos arbitraria en una tool de archivos, indirect prompt injection a través de una tool de procesamiento de documentos, y credenciales (un connection string de Postgres) filtradas directo desde la descripción de una tool.

La capa de IA es el punto acá: prompt injection, tool poisoning y system-prompt leakage no aparecen en ningún reporte de SAST/SCA —pero el mismo loop pentest autónomo que encadena un SQLi en DVWA también habla MCP sobre SSE y jailbreakea un LLM local, y cada hallazgo aterriza en el mismo workspace, al lado de los clásicos.

Priorización: una pasada de triage de FaradAI sobre el workspace, acotada a los 77 hallazgos critical + high , re-validó cada uno contra los targets vivos y empujó los veredictos de vuelta con evidencia adjunta: 65 confirmados, 2 cerrados (no se pudieron reproducir), 9 deduplicados (por ejemplo, un cluster de 20 de XStream colapsado a uno primario). De ahí salió un plan de patch priorizado de 71 items —41 bumps de dependencias (XStream → 1.4.21+, PyJWT → 2.13+, Flask → 2.3.2+), 29 fixes de código (queries parametrizadas, allow-list de algorithms en JWT, execute_command de MCP → argv con shell=False, evaluate_expression → allow-list por AST, canonicalización de paths, sacar la API key del system prompt del LLM), más cambios de config y de control de red.

Ese es el arco en una sola corrida: 620 en crudo → ~564 de amplitud estática → 48 exploits probados → 77 priorizados → 71 fixes accionables. Los scanners te dicen dónde mirar; FaradAI te dice qué consigue realmente un atacante —en web clásica, LLM y MCP por igual— y el triage te dice qué arreglar primero.

5. Lo que esto demuestra

Una app deliberadamente vulnerable es el lugar honesto para testear un programade seguridad, no solo un scanner:

  • Amplitud — Semgrep / Trivy / Gitleaks marcan todo estáticamente, en seis codebases y múltiples ecosistemas.
  • Prueba — FaradAI muestra cuáles de esos puede realmente explotar un atacante, y los encadena —incluyendo las clases específicas de IA (prompt injection, abuso de tools MCP) que las herramientas estáticas nunca ven.
  • Priorización — el triage colapsa el ruido en una cola rankeada y respaldada por evidencia.
  • Cierre — parcheá, re-escaneá, y Faraday te dice qué se arregló realmente.

Ese círculo completo —encontrar → probar → priorizar → arreglar → confirmar — es la diferencia entre una pila de hallazgos y un programa de seguridad, y podés ensayarlo todo de forma segura en estas seis apps antes de apuntarlo a producción.

6. ¿Setup? No hay

Nada de levantar Faraday, ni cablear tokens, ni registrar agentes. Todo es esto:

pip instalar Faraday-CLI
faraday-cli pentest --target https://yoursite.com

En la primera corrida el CLI te onboarda automáticamente:oma tu email, te manda un código de 6 dígitos para verificar, y crea tu instancia de FaradAI.(¿Preferís registrarte antes? Creá la cuenta directo en login.faradaysec.com con OAuth — Google, Microsoft, GitHub y más.) De ahí en más, faraday-cli pentest, , faraday-cli triage y faraday-cli scanners run funcionan solos — FaradAI se auto-descubre, así que no hay agent ids ni tokens de API que seteary tus imports estáticos (faraday-cli tool report) caen en el mismo workspace.

Configuras FaradAI una vez, en Faraday Personal, y todo lo anterior solo apunta a ello:

  1. Su instancia vive en login.faradaysec.com.
  2. En Security Scanner, el FaradAI Autonomous Pentest es donde configuras los objetivos, el alcance, las rondas y el workspace destino, y luego lo inicias manualmente desde la interfaz de usuario o automáticamente desde la integración continua (CI)
  3. Para acceder al panel de FaradAI (faradai-scan.apps.faradaysec.com/_ai/dashboard), debe hacer clic en FaradAI desde la interfaz de usuario para realizar la autenticación SSO. No se admite el acceso directo a la URL.

Dale a tu pentester de IA un hogar para sus hallazgos — Faraday Community · Faraday Personal →

Seguir leyendo

Los últimos artículos del blog

A medida que los programas de seguridad se desarrollan, más personas necesitan crear y gestionar su propio trabajo, y cada vez se invierte más tiempo en la navegación diaria. El Faraday 5.24 aborda ambos problemas. Proporciona una nueva función

20 de octubre de 2026

Este año, nuevamente formamos parte de Ekoparty con nuestro propio stand, donde recibimos a clientes, colegas y profesionales de ciberseguridad, mostramos cómo funciona FaradAI y desafiamos a la comunidad con nuestro

14 de octubre de 2026

Cualquiera puede encontrar un bug en una app deliberadamente vulnerable. La pregunta más difícil —la que realmente importa en producción— es: ¿podés correr un programa de seguridad de punta a

30 de septiembre de 2026

Manténgase informado, suscríbase a nuestro boletín

Introduzca su correo electrónico y no se pierda nunca las alertas y consejos de seguridad de los expertos de Faraday.

Faraday ayuda a grandes empresas, MSSPs y equipos de seguridad de aplicaciones a aprovechar mejor su ecosistema de seguridad, optimizando lo que ya utilizan.

Sede central

Laboratorio de investigación y desarrollo

Soluciones

Código abierto

2025 Faraday Security. Todos los derechos reservados.
Términos y condiciones | Política de privacidad
#zsiq_float, .zsiq_floatmain, [id^="zsiq"], [class^="zsiq"], iframe[id*="salesiq"], iframe[title*="chat" i] { display: none !important; visibility: hidden !important; opacity: 0 !important; pointer-events: none !important; }