
Docker-based lab reproducing CVE-2023-27163 SSRF in Request-Baskets, with exploitation verification, detection script, and network-isolation remediation.
Project: Vulnerability Research & Reproduction Lab β CVE-2023-27163
Author: Amulya Kaushik
Role: Cybersecurity R&D & Lab Content Development Intern Candidate
Server-Side Request Forgery in Request-Baskets β€ 1.2.1
A self-contained local research lab for reproducing, detecting, and remediating CVE-2023-27163 with defense-in-depth architecture.
| Field | Value |
|---|---|
| CVE ID | CVE-2023-27163 |
| CWE | CWE-918 β Server-Side Request Forgery (SSRF) |
| Affected Product | Request-Baskets |
| Affected Versions | β€ 1.2.1 |
| Fixed Version | 1.2.2 (Upstream source) / Defense-in-Depth Network Isolation |
| CVSS v3.1 Score | 6.5 (Medium) |
| CVSS Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| Attack Complexity | Low β single unauthenticated API call |
Note on Upstream Limitations & Remediation:
While CVE-2023-27163 tracks arbitrary forward URL validation, public container builds ofdarklynx/request-basketsdo not enforce loopback or private subnet filtering out of the box. Following real-world DevSecOps best practices, our lab demonstrates remediation through Defense-in-Depth Container Network Isolation. By isolating sensitive internal backends onto an internal-only Docker network (secure-internal-netwithinternal: true), the relay path is severed, mitigating the exploitability of the SSRF vulnerability even when running untrusted webhook forwarders.
This lab provides two discrete Docker Compose topologies:
docker-compose.yml): Request-Baskets and an internal secret echo service share the bridge network lab-net. Request-Baskets is mapped to host port 55556 (mapped from container port 55555).docker-compose.patched.yml): Request-Baskets is attached exclusively to public-net, while the internal echo service is attached to 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) β β
β βββββββββββββββββββββ β β βββββββββββββββββββββ β
βββββββββββββββββββββββββββ βββββββββββββββββββββββββββ
| Requirement | Minimum Version | Notes |
|---|---|---|
| Docker Engine | 20.10+ | Container virtualization runtime |
| Docker Compose | v2.0+ | Multi-container orchestration |
| Python | 3.8+ | CLI verification and detection tools |
Setup Python virtual environment and dependencies:
python3 -m venv .venv
source .venv/bin/activate
pip install requests fpdf2
Start the vulnerable environment (Request-Baskets v1.2.1 accessible at http://localhost:55556):
docker compose up -d
Verify that both containers are running:
docker compose ps
Expected output:
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
Confirm that the internal service is not directly reachable from the host:
curl http://localhost:5678 2>&1 || echo "Connection refused β internal service isolated as expected"
Execute the automated SSRF verification script:
python3 scripts/verify_vulnerability.py
What happens:
/api/baskets/ssrf-verification-basket setting forward_url: "http://internal-service:5678" and proxy_response: true.CONFIDENTIAL_DATA{INTERNAL_SSRF_DEMONSTRATION_SUCCESS} and outputs RESULT: VULNERABLE.Run the non-destructive audit probe:
python3 scripts/detect.py
What happens:
http://127.0.0.1:80) is accepted.AUDIT RESULT: VULNERABLE upon acceptance (HTTP 201) and cleans up the probe basket.Switch to the segmented remediated topology:
docker compose down
docker compose -f docker-compose.patched.yml up -d
python3 scripts/verify_vulnerability.py
Expected output:
==============================================================
[β] 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.
==============================================================
Tear down the environment when finished:
docker compose -f docker-compose.patched.yml down
The complete visual evidence portfolio for Deliverable 3 is maintained in the evidence/ directory:
| Artifact | Purpose | File Link | Description |
|---|---|---|---|
| Screenshot 1 | Environment Running | 01_lab_running.png | Shows vulnerable-request-baskets (port 55556) & isolated-internal-service running simultaneously on lab-net. |
| Screenshot 2 | SSRF Exploitation | 02_reproduction_ssrf.png | Displays exfiltrated CONFIDENTIAL_DATA{...} flag and VULNERABLE status. |
| Screenshot 3 | Defensive Detection Tool | 03_detection_tool_run.png | Displays dual-phase signature check and loopback audit flagging VULNERABLE. |
| Screenshot 4 | Remediation Verification | 04_remediation_verified.png | Proves relay failure (HTTP 502 / Host Unreachable) under segmented network defense. |
| Screenshot 5 | Web UI Configuration | 05_web_ui_ssrf.png | (Bonus) Browser capture of Request-Baskets UI settings configured with Proxy Response. |