
Laboratorio basado en Docker que reproduce la SSRF CVE-2023-27163 en Request-Baskets, con verificación de explotación, script de detección y remediación mediante aislamiento de red.
Proyecto: Laboratorio de Investigación y Reproducción de Vulnerabilidades — CVE-2023-27163
Autor: Amulya Kaushik
Rol: Candidato a Prácticas en I+D de Ciberseguridad y Desarrollo de Contenido para Laboratorios
Server-Side Request Forgery en Request-Baskets ≤ 1.2.1
Un laboratorio de investigación local autocontenido para reproducir, detectar y remediar CVE-2023-27163 con una arquitectura de defensa en profundidad.
| Campo | Valor |
|---|---|
| ID CVE | CVE-2023-27163 |
| CWE | CWE-918 — Server-Side Request Forgery (SSRF) |
| Producto Afectado | Request-Baskets |
| Versiones Afectadas | ≤ 1.2.1 |
| Versión Corregida | 1.2.2 (Código fuente upstream) / Aislamiento de Red con Defensa en Profundidad |
| Puntuación CVSS v3.1 | 6.5 (Media) |
| Vector CVSS | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| Complejidad del Ataque | Baja — una única llamada a la API sin autenticación |
Nota sobre Limitaciones del Upstream y Remediación:
Si bien CVE-2023-27163 rastrea la validación arbitraria de URL de reenvío, las compilaciones públicas de contenedores dedarklynx/request-basketsno aplican filtrado de loopback o subredes privadas de forma predeterminada. Siguiendo las mejores prácticas reales de DevSecOps, nuestro laboratorio demuestra la remediación mediante Aislamiento de Red de Contenedores con Defensa en Profundidad. Al aislar los backends internos sensibles en una red Docker solo interna (secure-internal-netconinternal: true), se corta la ruta de retransmisión, mitigando la explotabilidad de la vulnerabilidad SSRF incluso cuando se ejecutan reenviadores de webhooks no confiables.
Este laboratorio proporciona dos topologías discretas de Docker Compose:
docker-compose.yml): Request-Baskets y un servicio interno de eco de secretos comparten la red bridge lab-net. Request-Baskets está mapeado al puerto del host 55556 (mapeado desde el puerto del contenedor 55555).docker-compose.patched.yml): Request-Baskets está conectado exclusivamente a public-net, mientras que el servicio de eco interno está conectado a secure-internal-net (internal: true).docker-compose.yml)┌─────────────────────────────────────────────────────────┐
│ Docker: lab-net │
│ │
│ ┌─────────────────────┐ ┌────────────────────────┐ │
│ │ request-baskets │───▶│ internal-service │ │
│ │ (v1.2.1) │ │ (http-echo:5678) │ │
│ │ Port 55556 ◀──HOST │ │ NOT exposed to host │ │
│ └─────────────────────┘ └────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
▲
│ HTTP (port 55556)
│
┌────┴─────┐
│ Attacker │
└──────────┘
docker-compose.patched.yml)┌─────────────────────────┐ ┌─────────────────────────┐
│ public-net │ │ secure-internal-net │
│ │ │ (internal: true) │
│ ┌───────────────────┐ │ │ ┌───────────────────┐ │
│ │ request-baskets │ │ ✕ │ │ internal-service │ │
│ │ Port 55556◀─HOST │ │ ──/──▶ │ │ (http-echo:5678) │ │
│ └───────────────────┘ │ │ └───────────────────┘ │
└─────────────────────────┘ └─────────────────────────┘
| Requisito | Versión Mínima | Notas |
|---|---|---|
| Docker Engine | 20.10+ | Entorno de ejecución de virtualización de contenedores |
| Docker Compose | v2.0+ | Orquestación multi-contenedor |
| Python | 3.8+ | Herramientas de verificación y detección por CLI |
Configurar el entorno virtual de Python y las dependencias:
python3 -m venv .venv
source .venv/bin/activate
pip install requests fpdf2
Iniciar el entorno vulnerable (Request-Baskets v1.2.1 accesible en http://localhost:55556):
docker compose up -d
Verificar que ambos contenedores estén en ejecución:
docker compose ps
Salida esperada:
NAME IMAGE COMMAND SERVICE STATUS PORTS
isolated-internal-service hashicorp/http-echo:latest "/http-echo -text=CO…" internal-service Up 5678/tcp
vulnerable-request-baskets darklynx/request-baskets:v1.2.1 "/bin/sh -c /bin/ent…" request-baskets Up 0.0.0.0:55556->55555/tcp
Confirmar que el servicio interno no es accesible directamente desde el host:
curl http://localhost:5678 2>&1 || echo "Connection refused — internal service isolated as expected"
Ejecutar el script automatizado de verificación de SSRF:
python3 scripts/verify_vulnerability.py
Qué ocurre:
/api/baskets/ssrf-verification-basket estableciendo forward_url: "http://internal-service:5678" y proxy_response: true.CONFIDENTIAL_DATA{INTERNAL_SSRF_DEMONSTRATION_SUCCESS} y muestra RESULT: VULNERABLE.Ejecutar la sonda de auditoría no destructiva:
python3 scripts/detect.py
Qué ocurre:
http://127.0.0.1:80).AUDIT RESULT: VULNERABLE tras la aceptación (HTTP 201) y limpia el basket de sondeo.Cambiar a la topología remediada segmentada:
docker compose down
docker compose -f docker-compose.patched.yml up -d
python3 scripts/verify_vulnerability.py
Salida esperada:
==============================================================
[✓] REMEDIATION VERIFIED: TARGET SECURED
The Request-Baskets instance failed to reach the internal
isolated service (HTTP 502 / Host Unreachable).
Network segmentation successfully prevented SSRF data exfiltration.
==============================================================
Desmontar el entorno cuando haya terminado:
docker compose -f docker-compose.patched.yml down
El portafolio completo de evidencia visual para el Entregable 3 se mantiene en el directorio evidence/: