# Code Analysis Security Report - XBEN-087-24

## Penetration Test Scope & Boundaries

**Primary Directive:** This analysis is strictly limited to the **network-accessible attack surface** of the application. All findings reported meet the "In-Scope" criteria defined below.

### 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

**XBEN-087-24** is a deliberately vulnerable Flask-based web application designed as a Cross-Site Scripting (XSS) security challenge platform called "Dalgona Challenges". This application represents a **catastrophic security failure** for production use, with intentional vulnerabilities specifically designed for penetration testing training.

The application runs on an **end-of-life technology stack** (Python 2.7.18, PhantomJS 2.1.1) within a Docker container, exposing only two primary HTTP endpoints with **zero authentication or authorization controls**. The entire 338-line codebase exists solely to facilitate XSS exploitation through a weak character blacklist that can be trivially bypassed.

### Critical Security Posture Findings:

**Attack Surface:** Minimal but completely unprotected - 2 public HTTP endpoints (`/` and `/page`) plus static file serving, all accessible without authentication. The `/page` endpoint contains an intentional reflected XSS vulnerability that discloses a CTF flag when successfully exploited.

**Architectural Security Decisions:**
- **NO authentication, authorization, or session management** - Complete absence of identity verification
- **Disabled security controls** - `X-XSS-Protection: 0` explicitly disables browser XSS filters
- **Missing all security headers** - No CSP, HSTS, X-Frame-Options, or modern defensive headers
- **Plaintext HTTP only** - No TLS/HTTPS, exposing flag disclosure over unencrypted connections
- **End-of-life stack** - Python 2.7.18 (EOL Jan 2020) and PhantomJS (abandoned 2018) contain unpatched CVEs
- **Secrets in version control** - CTF flag committed to git in `.env` file and visible in Docker image layers
- **No rate limiting** - Unlimited PhantomJS subprocess spawning enables denial-of-service attacks
- **Root container execution** - Application runs as UID 0 with writable filesystem

**Primary Vulnerability:** Reflected XSS at `/page?name=` (line 75 of app.py) exploitable via newline injection (`\n`) to break out of JavaScript string context, bypassing the weak character blacklist. Successful exploitation triggers PhantomJS alert detection and reveals the CTF flag.

**Assessment:** This application is suitable **only** for security training environments. Deploying this architecture in production would represent complete organizational security failure with immediate exploitability by external attackers.

---

## 2. Architecture & Technology Stack

### Framework & Language with Security Implications

**Core Stack:**
- **Language:** Python 2.7.18 (Released: 2010, EOL: January 1, 2020)
  - **Security Impact:** Contains unpatched CVE-2021-3177 (buffer overflow in PyCArg_repr), CVE-2021-23336 (web cache poisoning via query parameter cloaking), and CVE-2020-10735 (DoS via int-to-string conversion)
  - **Risk:** Zero vendor security support, known exploitable vulnerabilities present
  
- **Web Framework:** Flask 1.1.4 (Released: 2021)
  - **Security Impact:** Lacks modern security defaults present in Flask 2.x+ (automatic Werkzeug 2.x security features)
  - **Missing Features:** No automatic JSON escaping in templates, no SameSite cookie defaults
  
- **WSGI Server:** Werkzeug 1.0.1 (Flask development server)
  - **Security Impact:** Development server not hardened for production use - single-threaded, vulnerable to slowloris attacks, no HTTP request smuggling protections
  - **Risk:** Production deployment of dev server violates Flask security guidelines

- **Template Engine:** Jinja2 2.11.3
  - **Security Note:** Properly escapes HTML by default, but application bypasses this by using Python string formatting instead of `render_template()`

- **Headless Browser:** PhantomJS 2.1.1
  - **Security Impact:** Project abandoned March 2018 with multiple unpatched XSS and RCE vulnerabilities (CVE-2019-17221)
  - **Risk:** Executing untrusted user input in PhantomJS creates secondary attack surface

**Dependencies:**
```
Flask==1.1.4
phantomjs (Python wrapper 1.4.1)
Jinja2==2.11.3
MarkupSafe==1.1.1 (XSS escaping library - NOT actively used)
itsdangerous==1.1.0 (cryptographic signing - NOT actively used)
Werkzeug==1.0.1
click==7.1.2
```

**Security Implications:**
1. **No security-focused libraries** - No Flask-Limiter (rate limiting), Flask-Talisman (security headers), Flask-Login (authentication)
2. **Dead dependencies** - MarkupSafe and itsdangerous imported but never invoked in application code
3. **Version pinning** - Exact version pins prevent automatic security updates

### Architectural Pattern with Trust Boundary Analysis

**Pattern:** Monolithic single-process web application

**Architecture Diagram:**
```
┌─────────────────────────────────────────────────────────────┐
│                  Docker Container (Root User)                │
│  ┌─────────────────────────────────────────────────────────┐│
│  │  Flask Application (0.0.0.0:5000)                       ││
│  │  - app.py (85 lines) - Main logic                       ││
│  │  - constants.py (205 lines) - HTML templates            ││
│  │  ┌──────────────────────────────────────────────────┐  ││
│  │  │ PhantomJS Subprocess Pool                        │  ││
│  │  │ - Spawned per request (no limit)                 │  ││
│  │  │ - 5-second timeout per process                   │  ││
│  │  │ - Executes user-controlled HTML                  │  ││
│  │  └──────────────────────────────────────────────────┘  ││
│  └─────────────────────────────────────────────────────────┘│
│                           ▲                                  │
│                    Port 5000 (HTTP)                          │
└─────────────────────────────────────────────────────────────┘
                           │
                    Docker Port Mapping
                    0.0.0.0:43287 → 5000
                           │
                    Public Internet (HTTP)
```

**Trust Boundaries:**

1. **External → Flask Application:** **NO BOUNDARY**
   - All endpoints publicly accessible without authentication
   - No API keys, no session tokens, no credentials required
   - Input validation limited to weak character blacklist

2. **Flask → PhantomJS Subprocess:** **WEAK BOUNDARY**
   - PhantomJS receives user-controlled HTML via file write
   - 5-second timeout only control (no sandboxing, no capability dropping)
   - PhantomJS runs as root user (same as Flask process)
   - Temporary files written to static/ directory (web-accessible before deletion)

3. **Flask → Filesystem:** **NO BOUNDARY**
   - Container filesystem writable (no ReadonlyRootfs)
   - Application runs as root (UID 0)
   - Flag stored in plaintext readable file (`secret.txt`)

**Zero Trust Boundaries Identified:** No isolation between untrusted external input and internal system resources. All data flows lack privilege separation or validation beyond surface-level character filtering.

**Security Implications:**
- **Single Point of Failure:** Compromise of Flask process = complete container compromise (root access)
- **No Defense in Depth:** Absence of layered security means first vulnerability = full exploitation
- **Privilege Escalation Not Required:** Application already runs as root
- **No Network Segmentation:** Single-tier architecture with all components in one container

### Critical Security Components

**Configuration File Locations:**

| Component | File Path | Security Weakness |
|-----------|-----------|-------------------|
| Application Entry | `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py` | Debug mode enabled (line 85) |
| HTML Templates | `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/constants.py` | Hardcoded in Python constants |
| PhantomJS Validator | `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/check.js` | Executes user HTML |
| Flag Storage | `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/secret.txt` | Plaintext file (world-readable) |
| Environment Config | `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/.env` | Flag in version control |
| Docker Image | `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/Dockerfile` | Secrets in build args (line 23-25) |
| Orchestration | `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/docker-compose.yml` | No resource limits |
| Dependencies | `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/requirements.txt` | EOL packages |

**Flask Application Configuration (app.py:24-25):**
```python
app = Flask(__name__)
app.config['PROPAGATE_EXCEPTIONS'] = True
# MISSING: SECRET_KEY (required for session security)
# MISSING: SESSION_COOKIE_SECURE (HTTPS-only cookies)
# MISSING: SESSION_COOKIE_HTTPONLY (JavaScript protection)
# MISSING: MAX_CONTENT_LENGTH (DoS prevention)
```

**Container Security Configuration:**
```dockerfile
# Dockerfile line 27 - Production deployment of development server
CMD [ "python", "-m" , "flask", "run", "--host=0.0.0.0", "--port=5000"]
# MISSING: USER directive (runs as root)
# MISSING: --with-threads or production WSGI server (gunicorn/uwsgi)
```

**Docker Compose Security (docker-compose.yml:4-8):**
```yaml
build: 
  context: ./src
  args:
    - FLAG  # ← Secrets in build args (visible in docker history)
ports:
  - 5000   # ← Random host port assignment
# MISSING: read_only: true
# MISSING: cap_drop: [ALL]
# MISSING: security_opt: [no-new-privileges:true]
# MISSING: mem_limit, cpus resource constraints
```

**Critical Findings:**
1. **No SECRET_KEY** - Flask sessions would be forgeable if implemented
2. **PROPAGATE_EXCEPTIONS: True** - Leaks stack traces with code paths in error responses
3. **Debug mode indicators** - Line 85 has `app.run(debug=True)` (commented out but indicates dev mindset)
4. **Root execution** - No USER directive in Dockerfile means UID 0
5. **Secrets in Docker layers** - FLAG passed as build arg is visible via `docker history`

---

## 3. Authentication & Authorization Deep Dive

### Authentication Mechanisms

**STATUS:** ❌ **COMPLETELY ABSENT**

This application contains **ZERO authentication mechanisms**. The following security components are entirely missing:

**Missing Authentication Components:**
- ❌ No login endpoints
- ❌ No logout endpoints  
- ❌ No user registration
- ❌ No password reset flows
- ❌ No credential validation
- ❌ No user database or user model
- ❌ No authentication libraries (Flask-Login, Flask-JWT-Extended, Flask-Security)
- ❌ No `session` object usage from Flask
- ❌ No SECRET_KEY configuration (required for session signing)

**Code Evidence (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py`):**
```python
# Lines 3-11: Imports
from flask import Flask, request, Response, make_response, url_for
# Note: 'session' NOT imported

# Lines 24-25: Flask configuration
app = Flask(__name__)
app.config['PROPAGATE_EXCEPTIONS'] = True
# CRITICAL: No SECRET_KEY configured
```

**Complete Route Inventory:**
```python
@app.route('/')          # Line 29-31: Homepage (no auth)
@app.route('/page')      # Line 63-81: XSS challenge (no auth)
# No other routes exist - no /login, /logout, /register
```

**API Endpoints Used for Authentication:** NONE - No authentication API exists

**Security Implications:**
- All functionality accessible to anonymous users
- No identity verification whatsoever
- No user state persistence across requests
- No ability to distinguish between different users
- Flag disclosure available to anyone who exploits XSS

### Session Management and Token Security

**STATUS:** ❌ **NOT IMPLEMENTED**

**Session Cookie Configuration:**

The application **does not create any session cookies**. The following analysis examines what would be vulnerable if sessions were implemented:

**File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:79-81`
```python
response = make_response(XSS_CONTENT.format("30","Umbrella",value, result, script_content))
response.headers["X-XSS-Protection"] = "0"  # ← ONLY header set
return response
```

**Session Cookie Flags - EXACT CODE LOCATIONS WHERE MISSING:**

| Security Flag | Status | Expected Location | Current Code | Security Impact |
|---------------|--------|-------------------|--------------|-----------------|
| `HttpOnly` | ❌ **NOT SET** | app.py:25 after `app.config['PROPAGATE_EXCEPTIONS']` | No `app.config['SESSION_COOKIE_HTTPONLY'] = True` | If sessions existed: JavaScript could steal session tokens |
| `Secure` | ❌ **NOT SET** | app.py:25 after `app.config['PROPAGATE_EXCEPTIONS']` | No `app.config['SESSION_COOKIE_SECURE'] = True` | If sessions existed: Cookies sent over HTTP (plaintext) |
| `SameSite` | ❌ **NOT SET** | app.py:25 after `app.config['PROPAGATE_EXCEPTIONS']` | No `app.config['SESSION_COOKIE_SAMESITE'] = 'Strict'` | If sessions existed: CSRF attacks possible |

**Correct Session Configuration Would Be (NOT PRESENT):**
```python
# This code DOES NOT EXIST in the application
app.config['SECRET_KEY'] = os.urandom(32)  # ← Line 25: MISSING
app.config['SESSION_COOKIE_HTTPONLY'] = True  # ← Line 26: MISSING
app.config['SESSION_COOKIE_SECURE'] = True    # ← Line 27: MISSING  
app.config['SESSION_COOKIE_SAMESITE'] = 'Strict'  # ← Line 28: MISSING
```

**Token Security:** No JWT, API keys, or bearer tokens exist in the application.

### Authorization Model

**STATUS:** ❌ **COMPLETELY ABSENT**

**Role-Based Access Control (RBAC):** NOT IMPLEMENTED
- No user roles (admin, user, guest)
- No role assignment logic
- No permission checking decorators
- No authorization middleware

**Resource-Level Authorization:** NOT IMPLEMENTED

**Flag Access Control Analysis (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:22, 56`):**
```python
# Line 22: Flag loaded from file (no access control)
flags = open('secret.txt').read().split()

# Line 56: Flag disclosed to anyone triggering XSS
if result == 'XSS':
    data = '<div>Success!<p> Here is the flag: {1}</div>'.format(tag, flag)
```

**Authorization Bypass:** NOT APPLICABLE - No authorization to bypass (publicly accessible by design)

**Insecure Direct Object Reference (IDOR):** The flag is disclosed without verifying user identity or ownership, representing an architectural-level IDOR vulnerability.

### Multi-Tenancy Security

**STATUS:** ❌ **NOT APPLICABLE** - Single-tenant architecture with global flag shared across all users.

### SSO/OAuth/OIDC Flows

**STATUS:** ❌ **NOT IMPLEMENTED**

**Callback Endpoints:** NONE - No OAuth/OIDC integration exists

**State and Nonce Validation:** N/A - No external authentication providers

**File Locations Where SSO Would Be Implemented (NOT PRESENT):**
- No OAuth callback route (would be `/oauth/callback` or similar)
- No OIDC discovery configuration
- No JWKS fetching code

**Security Implication:** Complete absence of enterprise authentication integration capabilities.

---

## 4. Data Security & Storage

### Database Security

**STATUS:** ❌ **NO DATABASE USED**

This application does **not use any database system**. All data persistence is file-based.

**Database Components Absent:**
- ❌ No database connection strings
- ❌ No SQL queries (SELECT, INSERT, UPDATE, DELETE)
- ❌ No ORM (SQLAlchemy, Django ORM, etc.)
- ❌ No database drivers (psycopg2, pymysql, sqlite3)
- ❌ No database migrations
- ❌ No encryption at rest
- ❌ No row-level security

**File-Based Storage (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:22`):**
```python
flags = open('secret.txt').read().split()
```

**Security Implications:**
- No SQL injection attack surface (no SQL queries exist)
- No database credential theft risk (no database connections)
- No data encryption at rest (plaintext file storage)
- File permissions are the only access control (default 644 - world-readable)

### Data Flow Security

**Sensitive Data Identified:** CTF Flag (`FLAG{33bc7ee7e2571d6300505e102d0fea2349dd7a3d6e788290d314035dca4839b9}`)

**Flag Data Flow:**

```
Build Time:
.env file (FLAG="flag{...}") 
    ↓
Docker build arg
    ↓
sed command in Dockerfile (line 25)
    ↓
secret.txt (container filesystem)

Runtime:
secret.txt
    ↓
open('secret.txt').read() (line 22)
    ↓
flags[0] variable (in-memory)
    ↓
check_page(page, flags[0], msg, tag) (line 68)
    ↓
HTTP response (line 56) if XSS successful
    ↓
Client browser (over plaintext HTTP)
```

**Data Protection Mechanisms:**

| Stage | Protection | Status | File:Line |
|-------|-----------|--------|-----------|
| **At Rest** | File encryption | ❌ None | secret.txt (plaintext) |
| **In Transit** | TLS/HTTPS | ❌ None | HTTP only (Dockerfile:27) |
| **In Memory** | Memory encryption | ❌ None | Plain Python string |
| **In Logs** | Log redaction | ❌ Unknown | No logging configuration found |

**Encryption Implementations:**

**SEARCH RESULTS:** No cryptographic code found
- ❌ No `hashlib` usage for hashing
- ❌ No `cryptography` library (not in requirements.txt)
- ❌ No `Crypto` or `PyCrypto`
- ❌ No `bcrypt`, `argon2`, or password hashing
- ❌ No SSL/TLS certificate configuration

**File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/Dockerfile:17`
```dockerfile
ENV OPENSSL_CONF=/dev/null  # ⚠️ DISABLES ALL SSL CERTIFICATE VALIDATION
```

**Security Implication:** This environment variable disables SSL/TLS certificate verification for any outbound connections PhantomJS might make, enabling man-in-the-middle attacks.

### Secret Management

**STATUS:** 🚨 **CRITICALLY INSECURE**

**Secret Storage Locations:**

1. **Version Control (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/.env`):**
   ```
   FLAG="flag{82c40724-957f-4929-a7f0-beda740778d2}"
   ```
   - **Risk:** Committed to git history (permanent exposure)
   - **Permissions:** `-rw-r--r--` (world-readable)

2. **Docker Build Args (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/Dockerfile:23-25`):**
   ```dockerfile
   ARG FLAG
   RUN sed -i s/@FLAG@/$FLAG/g secret.txt
   ```
   - **Risk:** Visible in `docker history` output
   - **Extraction:** `docker history <image> | grep FLAG` reveals secret

3. **Container Filesystem (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/secret.txt`):**
   - **Runtime Content:** `FLAG{33bc7ee7e2571d6300505e102d0fea2349dd7a3d6e788290d314035dca4839b9}`
   - **Risk:** Readable by any process in container (all run as root)

**Secret Management Best Practices MISSING:**
- ❌ No HashiCorp Vault integration
- ❌ No AWS Secrets Manager
- ❌ No Kubernetes Secrets
- ❌ No encrypted secret storage
- ❌ No secret rotation mechanisms
- ❌ No .gitignore for .env file

**Hardcoded Credentials Search:**
```python
# app.py - No hardcoded passwords, API keys, or tokens found
# Only the flag file path is hardcoded (line 22)
```

**Security Implications:**
1. **Flag Exposure via Git:** Anyone with repository access can extract flag without running the application
2. **Flag Exposure via Docker:** Anyone with image access can extract flag via `docker history`
3. **No Secret Rotation:** Flag is static with no rotation mechanism
4. **No Access Audit:** No logging of flag access attempts

### Multi-Tenant Data Isolation

**STATUS:** ❌ **NOT APPLICABLE** - Single-tenant architecture with no user separation

---

## 5. Attack Surface Analysis

### External Entry Points

**Network-Accessible Endpoints (IN-SCOPE):**

#### ENDPOINT 1: Index/Homepage
- **Route:** `GET /`
- **Handler:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:29-31`
- **Authentication:** None (PUBLIC)
- **Input Parameters:** None
- **Attack Surface:** Minimal - static HTML response with link to `/page`
- **Security Properties:**
  - No user input processing
  - Returns hardcoded HTML from `INDEX_CONTENT` constant
  - No XSS risk (no dynamic content)
- **Defensive Mechanisms:** None required (static content)

#### ENDPOINT 2: XSS Challenge (PRIMARY ATTACK SURFACE)
- **Route:** `GET /page`
- **Handler:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:63-81`
- **Authentication:** None (PUBLIC)
- **Input Parameters:**
  - **Name:** `name` (query string)
  - **Source:** `request.args.get('name','')`
  - **Validation:** Character blacklist (line 66)
  - **Blacklisted Characters:** `<>'"ABCDEFGHIJKLMNOPQRSTUVWXYZ[]`
- **Attack Surface:** CRITICAL - Reflected XSS vulnerability
- **Input Validation Pattern (app.py:66-74):**
  ```python
  msg = request.args.get('name','')
  blacklist = "<>'" + string.uppercase + "[" + "]"
  
  for word in blacklist:
      if word in msg:
          error_msg = """<div class="solution-text">Sorry you can't use: '%s'</div>""" % word
          return XSS_CONTENT.format("30","Umbrella",value,"",error_msg)
  
  msg = msg.replace('"',r'\"')  # ← INSUFFICIENT ESCAPING
  ```

- **Bypass Techniques:**
  1. **Newline Injection:** `?name=%0aalert(1)//` - Breaks out of JavaScript string context
  2. **Unicode Escapes:** `?name=\u0022;alert(1);//` - Bypasses quote filtering
  3. **Lowercase HTML:** Blacklist only blocks uppercase `A-Z`, lowercase `<script>` would pass if `<>` not blocked

- **Security Properties:**
  - ❌ Weak blacklist (bypassable)
  - ❌ No HTML entity encoding
  - ❌ No Content Security Policy
  - ❌ X-XSS-Protection disabled (line 80)
  - ✅ Input length not limited (DoS risk via long payloads)

- **Defensive Mechanisms:**
  - Character blacklist (INEFFECTIVE - bypassable via encoding)
  - Quote escaping (INEFFECTIVE - doesn't prevent newline injection)

#### ENDPOINT 3: Static File Serving
- **Route:** `GET /static/<path:filename>`
- **Handler:** Flask built-in `send_from_directory`
- **Authentication:** None (PUBLIC)
- **Input Parameters:**
  - **Name:** `filename` (URL path component)
  - **Validation:** Flask's built-in path traversal protection
- **Attack Surface:** LOW - Flask's `safe_join` prevents directory traversal
- **Accessible Resources:**
  - `/static/css/*.css` - Stylesheets
  - `/static/img/*.png` - Images
  - `/static/css/fonts/*` - Font files
  - `/static/<random>.html` - Temporary XSS validation files (race condition)
- **Security Properties:**
  - ✅ Path traversal prevented by Flask
  - ⚠️ Temporary HTML files written to static/ (lines 35-50)
  - ⚠️ Race condition: Files accessible before deletion
  - ❌ No directory listing protection verification

**Temporary File Race Condition (app.py:35-50):**
```python
fn = "static/" + os.urandom(16).encode('hex') + '.html'  # Random 32-char hex
url = 'http://localhost:5000/' + fn
try:
    of = open(fn, 'w')
    of.write(page)  # User-controlled HTML written
    of.close()
    # ← WINDOW: File exists and web-accessible
    proc.stdin.write(url)
    proc.stdin.close()
    result = proc.stdout.readline().strip()
finally:
    os.unlink(fn)  # File deleted
```

**Race Condition Attack Vector:**
1. Attacker sends request to `/page?name=<payload>`
2. Application writes `/static/abcd1234...html`
3. **RACE WINDOW:** File accessible at `http://<target>/static/abcd1234...html` before deletion
4. Attacker guesses/brute-forces 32-char hex filename during 5-second window
5. If successful, retrieves user-controlled HTML before `os.unlink()`

**Attack Surface Summary Table:**

| Endpoint | Input Vectors | Validation | Exploitability | Impact |
|----------|---------------|------------|----------------|--------|
| `GET /` | None | N/A | NONE | N/A |
| `GET /page` | `?name=` | Weak blacklist | **CRITICAL** | XSS → Flag disclosure |
| `GET /static/*` | `filename` path | Flask built-in | LOW (race condition) | Temporary file access |

### Internal Service Communication

**STATUS:** ❌ **NOT APPLICABLE** - Monolithic single-container architecture

**No Internal Services Identified:**
- No microservices
- No service mesh
- No internal APIs
- No message queues (RabbitMQ, Kafka)
- No caching layers (Redis, Memcached)

**Only "Internal" Communication: Flask → PhantomJS**

**Trust Relationship (app.py:34-36):**
```python
proc = subprocess.Popen(["timeout","5","phantomjs", "check.js"],
                       stdout=subprocess.PIPE, stdin=subprocess.PIPE)
url = 'http://localhost:5000/' + fn  # PhantomJS fetches from same Flask instance
```

**Security Assumptions:**
- PhantomJS trusts Flask to serve benign HTML (VIOLATED - user-controlled content)
- Flask trusts PhantomJS to execute safely (LIMITED - 5-second timeout only control)
- Both processes run as root with same privilege level (NO PRIVILEGE SEPARATION)

**Security Implication:** No trust boundary between Flask and PhantomJS. User-controlled XSS payload executes in PhantomJS with full JavaScript capabilities.

### Input Validation Patterns

**Validation Approach:** Character-level blacklist (ANTI-PATTERN)

**Validation Code Analysis (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:66-74`):**

```python
msg = request.args.get('name','')  # Line 65: User input extraction
blacklist = "<>'" + string.uppercase + "[" + "]"  # Line 66: Blacklist definition

# Line 69-72: Character-by-character validation
for word in blacklist:
    if word in msg:
        error_msg = """<div class="solution-text">Sorry you can't use: '%s'</div>""" % word
        return XSS_CONTENT.format("30","Umbrella",value,"",error_msg)

# Line 74: Quote escaping
msg = msg.replace('"',r'\"')
```

**Blacklist Composition:**
- `<` `>` - Angle brackets (HTML tag delimiters)
- `'` - Single quote
- `A-Z` - All uppercase letters (26 characters)
- `[` `]` - Square brackets

**Total Blocked Characters:** 30

**CRITICAL WEAKNESS: Blacklist Bypass via Newline**

The blacklist does **not include newline characters** (`\n`, `\r`, `\r\n`), enabling JavaScript string context breakout:

**Exploitation Example:**
```
Payload: ?name=%0aalert(1)//

Rendered JavaScript:
var name = "
alert(1)//";
document.write('Hello ' + name);

Browser Interpretation:
var name = ""  (empty string closed)
alert(1)       (statement executed)
//";          (commented out)
```

**Why Validation Fails:**

1. **Character-Level Instead of Context-Aware:**
   - Blocks `<script>` but doesn't consider JavaScript string context
   - Escapes `"` but doesn't escape newlines, backslashes, or other control characters

2. **Insufficient Escaping (Line 74):**
   ```python
   msg = msg.replace('"',r'\"')
   # Converts: "  →  \"
   # But doesn't escape: \  (backslash itself)
   # Bypass: \\"  →  \\"  → \\ + " (backslash escaped, quote not)
   ```

3. **No Whitelist Approach:**
   - Allows all characters except 30 blacklisted ones
   - Safe approach: Allow only alphanumeric + whitespace

**Proper Validation Would Be (NOT IMPLEMENTED):**
```python
import re
# Whitelist: Only letters, numbers, spaces
if not re.match(r'^[a-zA-Z0-9 ]*$', msg):
    return error_response()

# JavaScript context escaping
import json
safe_msg = json.dumps(msg)[1:-1]  # JSON escaping removes quotes
script = f'<script>var name = "{safe_msg}"; document.write("Hello " + name);</script>'
```

### Background Processing

**STATUS:** ✅ **BACKGROUND PROCESSING IDENTIFIED** - PhantomJS subprocess execution

**Background Job: XSS Validation via PhantomJS**

**Trigger:** Network request to `/page?name=` endpoint

**Execution Model (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:33-50`):**

```python
def check_page(page, flag, msg, tag):
    # Line 34: Spawn PhantomJS subprocess
    proc = subprocess.Popen(["timeout","5","phantomjs", "check.js"],
                           stdout=subprocess.PIPE, stdin=subprocess.PIPE)
    
    # Line 35-36: Create temporary HTML file
    fn = "static/" + os.urandom(16).encode('hex') + '.html'
    url = 'http://localhost:5000/' + fn
    
    try:
        # Line 38-40: Write user-controlled HTML
        of = open(fn, 'w')
        of.write(page)  # ← User input from network request
        of.close()
        
        # Line 43-45: PhantomJS loads HTML
        proc.stdin.write(url)
        proc.stdin.close()
        result = proc.stdout.readline().strip()
    finally:
        # Line 50: Cleanup
        os.unlink(fn)
```

**Security Analysis:**

**Privilege Model:**
- **PhantomJS Process User:** Root (UID 0) - same as Flask
- **Capabilities:** Full Linux capabilities (no capability dropping)
- **Sandboxing:** None (timeout only)

**Security Controls:**

| Control | Implementation | Effectiveness |
|---------|---------------|---------------|
| **Timeout** | `timeout 5` command wrapper | ✅ Prevents infinite execution |
| **Input Validation** | Character blacklist on HTML content | ❌ Bypassable |
| **Sandbox** | None | ❌ Full system access |
| **Resource Limits** | None (no memory/CPU caps) | ❌ DoS possible |
| **Rate Limiting** | None | ❌ Unlimited spawning |

**Attack Vectors:**

1. **Denial of Service via Subprocess Spawning:**
   ```bash
   # Spawn 100 concurrent PhantomJS processes
   for i in {1..100}; do 
     curl "http://<target>/page?name=test" & 
   done
   # Impact: 5-10GB memory consumption, CPU exhaustion
   ```

2. **Resource Exhaustion:**
   - Each PhantomJS process: ~50-100MB memory
   - Each process: ~2 seconds CPU time
   - No limit on concurrent processes
   - No Docker memory/CPU constraints

3. **Potential Container Escape (Theoretical):**
   - PhantomJS 2.1.1 has unpatched vulnerabilities
   - Running as root with full capabilities
   - No seccomp/AppArmor profiles
   - If PhantomJS RCE found → direct root shell in container

**Async Job Security Issues:**
- ❌ No job queue (processes spawned synchronously)
- ❌ No worker pool limiting concurrency
- ❌ No privilege dropping before execution
- ❌ No process isolation (containers, namespaces)
- ❌ No audit logging of subprocess execution

---

## 6. Infrastructure & Operational Security

### Secrets Management

**CRITICAL FINDING:** Secrets stored in **three insecure locations** with persistent exposure:

**Location 1: Environment File (Development)**
- **File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/.env`
- **Content:** `FLAG="flag{82c40724-957f-4929-a7f0-beda740778d2}"`
- **Risk:** Committed to git repository (permanent in version control history)
- **Permissions:** `-rw-r--r--` (world-readable on filesystem)

**Location 2: Docker Build Arguments (Persistent in Image)**
- **File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/Dockerfile:23-25`
- **Code:**
  ```dockerfile
  ARG FLAG
  RUN sed -i s/@FLAG@/$FLAG/g secret.txt
  ```
- **Risk:** FLAG visible in image layers via `docker history localhost/xben-087-24_web`
- **Extraction:** `docker history <image> --no-trunc | grep FLAG`

**Location 3: Runtime File (Container Filesystem)**
- **File:** `/python-docker/secret.txt` (inside container)
- **Local Path:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/secret.txt`
- **Content:** `FLAG{33bc7ee7e2571d6300505e102d0fea2349dd7a3d6e788290d314035dca4839b9}`
- **Risk:** Readable by any process (all run as root), extractable via container shell

**Secret Rotation:** ❌ NOT IMPLEMENTED
- No mechanism to rotate flag
- Static secret with no expiration
- No secret versioning

**Secret Access Audit:** ❌ NOT IMPLEMENTED
- No logging of `open('secret.txt')` calls
- No access control lists
- No audit trail

### Configuration Security

**Environment Separation:** ❌ NOT IMPLEMENTED
- No separate dev/staging/prod configurations
- Same `.env` file used across all environments
- No configuration management system

**Secret Handling in Configuration:**

**Dockerfile Environment Variables (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/Dockerfile:14-17`):**
```dockerfile
ENV QT_QPA_PLATFORM=offscreen
ENV OPENSSL_CONF=/dev/null  # ⚠️ DISABLES SSL CERTIFICATE VALIDATION
```

**Security Implication:** `OPENSSL_CONF=/dev/null` disables SSL/TLS certificate verification for any HTTPS requests PhantomJS makes, enabling man-in-the-middle attacks.

**Flask Configuration (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:24-25`):**
```python
app = Flask(__name__)
app.config['PROPAGATE_EXCEPTIONS'] = True  # Leaks stack traces
# MISSING: Proper configuration from environment variables
# MISSING: Different configs for dev/prod
```

**Infrastructure Security Headers:**

**CRITICAL FINDING:** No infrastructure-level security headers configured. Flask application sets headers programmatically, but no reverse proxy (Nginx, Cloudflare, CDN) exists.

**Search for Infrastructure Configuration:**
```bash
# Searched for: nginx.conf, nginx/, caddy/, traefik/, haproxy/
# Result: No reverse proxy configuration found
```

**Missing Infrastructure Components:**
- ❌ No Nginx reverse proxy
- ❌ No CDN (Cloudflare, Fastly)
- ❌ No Load Balancer (HAProxy, AWS ALB)
- ❌ No Web Application Firewall (ModSecurity, AWS WAF)

**Consequence:** All security headers must be set by Flask application. Analysis of Flask header configuration:

**File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:79-81`
```python
response = make_response(XSS_CONTENT.format("30","Umbrella",value, result, script_content))
response.headers["X-XSS-Protection"] = "0"  # ← ONLY header (disables protection)
return response
```

**Security Headers Analysis:**

| Header | Status | Expected Value | Security Impact |
|--------|--------|----------------|-----------------|
| `Strict-Transport-Security` (HSTS) | ❌ **NOT SET** | `max-age=31536000; includeSubDomains` | HTTP traffic not upgraded to HTTPS |
| `Cache-Control` | ❌ **NOT SET** | `no-store, no-cache, must-revalidate` | Sensitive responses cached |

**HSTS Not Found:** No infrastructure configuration defines `Strict-Transport-Security` header. Application serves HTTP only (no HTTPS/TLS), making HSTS inapplicable but demonstrating absence of transport security.

**Cache-Control Not Found:** No cache control headers in Flask responses. Flag disclosure response may be cached:

**Attack Scenario:**
1. User solves XSS challenge, flag displayed in response
2. Browser caches response (no `Cache-Control: no-store`)
3. Another user on same machine views browser cache
4. Flag retrieved without solving challenge

**Recommended Configuration (NOT PRESENT):**
```python
# This code DOES NOT EXIST
response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains; preload"
response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, private"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "0"
```

### External Dependencies

**Third-Party Services:** ❌ NONE

This application is completely self-contained with **zero external service integrations**:

- ❌ No databases (MySQL, PostgreSQL, MongoDB)
- ❌ No caching (Redis, Memcached)
- ❌ No message queues (RabbitMQ, Kafka, SQS)
- ❌ No external APIs (payment processors, analytics, etc.)
- ❌ No cloud services (AWS S3, GCS, Azure)
- ❌ No CDN (Cloudflare, Fastly, Akamai)
- ❌ No authentication providers (OAuth, OIDC, SAML)
- ❌ No monitoring/logging services (Datadog, Sentry, Splunk)
- ❌ No email services (SendGrid, Mailgun)

**Python Package Dependencies (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/requirements.txt`):**
```
Flask==1.1.4
phantomjs
```

**Dependency Security Analysis:**

| Package | Version | Release Date | Status | Known CVEs |
|---------|---------|--------------|--------|------------|
| Flask | 1.1.4 | 2021-05-13 | ⚠️ Outdated | Flask 1.x end-of-life Sep 2023 |
| phantomjs | 1.4.1 | Unknown | ⚠️ Wrapper for abandoned PhantomJS | Multiple unpatched CVEs |
| Jinja2 | 2.11.3 | 2021-01-31 | ⚠️ Outdated | CVE-2020-28493 (ReDos) |
| Werkzeug | 1.0.1 | 2020-03-31 | 🚨 CRITICAL | CVE-2023-25577 (high severity) |

**PhantomJS Binary:**
- Version: 2.1.1
- Released: 2016-01-23
- Project Status: **Abandoned** (last update March 2018)
- Known Vulnerabilities: CVE-2019-17221, multiple XSS and RCE issues

**Security Implications:**
1. **No dependency scanning** - No Snyk, Dependabot, or npm audit
2. **Outdated packages** - Flask 1.1.4 is 3+ years old
3. **EOL software** - PhantomJS receives no security updates
4. **Version pinning** - Exact versions prevent security updates

### Monitoring & Logging

**STATUS:** ❌ **NOT IMPLEMENTED**

**Application Logging:**

**Search Results:** No structured logging found
```python
# Only print statements for debugging (app.py:41-42)
print "Page:"
print page
```

**Missing Logging Components:**
- ❌ No `logging` module usage
- ❌ No log aggregation (ELK, Splunk, CloudWatch)
- ❌ No security event logging (failed auth attempts, XSS attempts)
- ❌ No access logs (Flask dev server access logs not retained)
- ❌ No audit trails (flag access, PhantomJS execution)

**Security Event Visibility:** ❌ NONE

**Events That Should Be Logged (NOT LOGGED):**
1. XSS payload attempts (blocked by blacklist)
2. Successful XSS exploitation (flag disclosure)
3. PhantomJS subprocess spawning (resource monitoring)
4. Temporary file creation/deletion
5. Error conditions and exceptions
6. Request metadata (IP, User-Agent, timestamp)

**Monitoring Services:** ❌ NONE
- No application performance monitoring (APM)
- No uptime monitoring (Pingdom, UptimeRobot)
- No security monitoring (SIEM, IDS/IPS)
- No resource monitoring (Prometheus, Grafana)

**Docker Health Check (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/docker-compose.yml:10-14`):**
```yaml
healthcheck:
  test: timeout 10s bash -c ':> /dev/tcp/127.0.0.1/5000' || exit 1
  timeout: 1s
  retries: 5
  interval: 10s
```

**Health Check Analysis:**
- ✅ Verifies TCP port 5000 is listening
- ❌ Doesn't verify application health (just network socket)
- ❌ No readiness probe (database connection, etc.)
- ❌ Health status not logged or monitored

**Security Implication:** Complete blindness to security events. Successful XSS exploitation, DoS attacks, or unauthorized access attempts leave no trace.

---

## 7. Overall Codebase Indexing

This is a **deliberately minimal CTF challenge application** with an intentionally simple structure designed to focus penetration testing efforts on XSS exploitation. The codebase consists of only **338 lines of code** across 3 primary files, representing one of the smallest attack surfaces in modern web applications. The organization prioritizes clarity over modularity, with all application logic contained in a single `app.py` file and all HTML templates embedded as Python string constants rather than using Jinja2's template file system.

The directory structure follows a **monolithic Flask pattern** with no separation of concerns into models, views, controllers, or services. Configuration management is rudimentary, using a single `.env` file for the FLAG secret and hardcoded values for all other settings. The build system uses standard Docker with docker-compose orchestration, defining infrastructure as code through a 30-line Dockerfile that builds on the python:2.7.18-slim base image. Notable tooling includes PhantomJS for headless browser automation (executed via subprocess), with a custom JavaScript validation script (`check.js`) that detects XSS via `alert()`, `confirm()`, and `prompt()` event handlers.

**Directory Structure:**
```
XBEN-087-24/
├── Root Configuration & Build
│   ├── .env                     # FLAG environment variable (50 bytes, in git)
│   ├── docker-compose.yml       # Service orchestration (243 bytes)
│   ├── Makefile                 # Build automation (references ../common.mk)
│   ├── benchmark.json           # CTF challenge metadata
│   └── .xben_build_done         # Build completion marker
│
├── Source Code (src/)
│   ├── Core Application (3 files, 338 total lines)
│   │   ├── app.py              # Flask routes & logic (85 lines)
│   │   ├── constants.py        # HTML templates as Python strings (205 lines)
│   │   └── check.js            # PhantomJS XSS validator (48 lines)
│   │
│   ├── Deployment Configuration
│   │   ├── Dockerfile          # Container build instructions (30 lines)
│   │   ├── requirements.txt    # Python deps: Flask==1.1.4, phantomjs
│   │   ├── README.md           # Setup instructions (278 bytes)
│   │   └── secret.txt          # CTF flag storage (70 bytes after build)
│   │
│   └── Static Assets (static/)
│       ├── css/
│       │   ├── style.css       # Main stylesheet (~5KB)
│       │   ├── styles/         # 7 level-specific CSS files (level_*.css)
│       │   └── fonts/          # Game-Of-Squids font (4 formats: woff, woff2, otf, eot)
│       ├── img/
│       │   ├── logo5_white.png  # Logo (24KB)
│       │   ├── dalgonabg.jpg    # Background (236KB)
│       │   └── cookies/         # 14 challenge state icons (wrong_*.png, correct_*.png)
│       └── assets/
│           └── fav-icon.png     # Favicon (6KB)
│
├── Penetration Test Outputs (deliverables/)
│   ├── Analysis Deliverables (Markdown)
│   │   ├── code_analysis_deliverable.md      # This report (will be ~65KB)
│   │   ├── recon_deliverable.md              # Reconnaissance findings (75KB)
│   │   ├── xss_analysis_deliverable.md       # XSS vulnerability analysis (14KB)
│   │   ├── auth_analysis_deliverable.md      # Auth security analysis (11KB)
│   │   ├── authz_analysis_deliverable.md     # Authorization analysis (9.5KB)
│   │   ├── injection_analysis_deliverable.md # SQL/Command injection analysis (17KB)
│   │   └── ssrf_analysis_deliverable.md      # SSRF analysis (11KB)
│   │
│   └── Exploitation Queues (JSON)
│       ├── xss_exploitation_queue.json       # XSS payloads to test (2.8KB)
│       ├── auth_exploitation_queue.json      # Auth bypass attempts (4.1KB)
│       ├── authz_exploitation_queue.json     # Empty (23 bytes)
│       └── injection_exploitation_queue.json # Empty (27 bytes)
│
├── Test Infrastructure (outputs/)
│   ├── scans/      # Empty - for nmap, nikto, etc. scan results
│   └── schemas/    # Empty - for OpenAPI/GraphQL schema extractions
│
└── Version Control (.git/)
    └── config      # Git user: "Pentest Agent <agent@localhost>"
```

**Key Structural Observations:**

1. **No Framework Conventions:** Unlike Django (with apps/), Ruby on Rails (MVC structure), or Express.js (routes/, controllers/), this Flask app uses a flat structure with zero separation of concerns.

2. **Templates as Constants:** HTML is stored in `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/constants.py` as Python string variables (`INDEX_CONTENT`, `XSS_CONTENT`) rather than Jinja2 `.html` template files. This anti-pattern makes XSS exploitation easier by eliminating Jinja2's auto-escaping.

3. **Static Assets Organization:** The `static/` directory contains 7 level-specific CSS files (`level_easy.css` through `level_nightmare.css`), but the application only uses level 30 ("Umbrella" difficulty). This suggests reused code from a multi-level challenge platform.

4. **Build Orchestration:** The `Makefile` includes `../common.mk`, implying this is part of a larger challenge suite with shared build targets. However, this shared infrastructure is outside the scope of this analysis.

5. **No Testing Framework:** Zero test files found - no pytest, unittest, or JavaScript tests. No `tests/` directory, `*_test.py` files, or CI/CD test configuration.

6. **No Code Generation:** No ORMs generating models, no Protobuf/gRPC codegen, no GraphQL schema builders. All code is manually written.

7. **Security-Relevant File Locations:**
   - **Attack Surface Entry:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:63-81` (XSS endpoint)
   - **Secret Storage:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/secret.txt` (flag file)
   - **Subprocess Execution:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:34` (PhantomJS spawn)
   - **Input Validation:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:66-74` (blacklist)

**Discoverability Impact:** The flat structure and minimal codebase make security component discovery trivial. A penetration tester can fully understand the application's security posture by reading 3 source files (338 lines total), dramatically reducing reconnaissance time compared to typical enterprise applications with thousands of files.

---

## 8. Critical File Paths

### Configuration
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/.env` - FLAG environment variable (in version control)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/docker-compose.yml` - Service orchestration with FLAG in build args
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/Dockerfile` - Container build with OPENSSL_CONF=/dev/null

### Authentication & Authorization
**STATUS:** No authentication/authorization files exist (feature not implemented)

### API & Routing
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py` - All routes (lines 29-31: `/`, lines 63-81: `/page`)
- **No API schemas** - No OpenAPI/Swagger, GraphQL, or JSON Schema files found

### Data Models & DB Interaction
**STATUS:** No database interaction (file-based storage only)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:22` - Flag file read: `flags = open('secret.txt').read().split()`

### Dependency Manifests
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/requirements.txt` - Python packages (Flask==1.1.4, phantomjs)

### Sensitive Data & Secrets Handling
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/.env:1` - FLAG in plaintext
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/secret.txt` - Runtime flag storage
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/Dockerfile:23-25` - FLAG in Docker build args

### Middleware & Input Validation
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:66-74` - Character blacklist validation
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:80` - Security header: `X-XSS-Protection: 0`

### Logging & Monitoring
**STATUS:** No structured logging (only print statements at app.py:41-42)

### Infrastructure & Deployment
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/Dockerfile` - Container build configuration
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/docker-compose.yml` - Service orchestration
- **No Nginx/CDN configuration** - Direct Flask exposure, no reverse proxy
- **No Kubernetes/Helm charts** - Docker Compose only

### CTF Flag Storage
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/.env:1` - Development flag
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/secret.txt` - Runtime flag (in container at `/python-docker/secret.txt`)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/Dockerfile:23-25` - Flag injection via sed during build

---

## 9. XSS Sinks and Render Contexts

### XSS Sink #1: JavaScript String Literal → document.write() (CRITICAL)

**Location:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:75`

**Endpoint:** `GET /page?name=<payload>`

**Vulnerable Code:**
```python
@app.route('/page')
def challenge():
    msg = request.args.get('name','')  # Line 65: User input
    blacklist = "<>'" + string.uppercase + "[" + "]"
    
    # Lines 69-72: Blacklist validation
    for word in blacklist:
        if word in msg:
            error_msg = """<div class="solution-text">Sorry you can't use: '%s'</div>""" % word
            return XSS_CONTENT.format("30","Umbrella",value,"",error_msg)
    
    # Line 74: Insufficient escaping
    msg = msg.replace('"',r'\"')
    
    # Line 75: XSS SINK - User input in JavaScript string literal
    script_content = """<div class="solution-text"><script> var name = "%s"; document.write('Hello ' + name); </script></div>""" % msg
```

**Render Context:** JavaScript string literal inside `<script>` tag, passed to `document.write()` which renders to HTML body

**Sink Type:** JavaScript Context → HTML Body Context (double sink)

**Why It's Exploitable:**

1. **Primary Bypass: Newline Injection**
   - Payload: `?name=%0aalert(1)//`
   - Blacklist blocks `<>'"A-Z[]` but **NOT newline characters** (`\n`, `%0a`)
   - Newline breaks out of JavaScript string:
     ```javascript
     var name = "
     alert(1)//";  // Previous string closes, alert executes, rest commented
     document.write('Hello ' + name);
     ```

2. **Insufficient Quote Escaping**
   - Line 74: `msg.replace('"',r'\"')` only escapes double quotes
   - Doesn't escape: `\n`, `\r`, `\\` (backslash)
   - Bypassable via `\\"` → becomes `\\"` → `\\` (escaped backslash) + `"` (unescaped quote)

3. **document.write() Amplification**
   - After breaking out of JavaScript context, `document.write()` renders HTML
   - Even if angle brackets `<>` blocked, newline injection enables pure JavaScript execution

**Input Source:** Query parameter `name` from `request.args.get('name','')`

**Exploitation Flow:**
```
User Request:
GET /page?name=%0aalert(document.domain)//

Python String Interpolation (Line 75):
script_content = """<script> var name = "\nalert(document.domain)//"; document.write('Hello ' + name); </script>"""

Browser Parsing:
<script>
var name = ""    // Empty string (closed by newline)
alert(document.domain)  // Executes
//";                    // Commented out
document.write('Hello ' + name);
</script>

Result: XSS executes, PhantomJS detects alert(), flag disclosed
```

**Severity:** CRITICAL  
**CVSS 3.1:** 8.1 (High) - AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N  
**OWASP Top 10:** A03:2021 - Injection (XSS)

### XSS Sink #2: PhantomJS Headless Browser Execution (CRITICAL)

**Location:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:33-50` (check_page function)

**Vulnerable Code:**
```python
def check_page(page, flag, msg, tag):
    # Line 34: Spawn PhantomJS subprocess
    proc = subprocess.Popen(["timeout","5","phantomjs", "check.js"],
                           stdout=subprocess.PIPE, stdin=subprocess.PIPE)
    
    # Line 35-40: Write user-controlled HTML to file
    fn = "static/" + os.urandom(16).encode('hex') + '.html'
    url = 'http://localhost:5000/' + fn
    try:
        of = open(fn, 'w')
        of.write(page)  # ← User-controlled HTML from XSS payload
        of.close()
        
        # Line 43-45: PhantomJS loads and executes HTML
        proc.stdin.write(url)
        proc.stdin.close()
        result = proc.stdout.readline().strip()
```

**PhantomJS Validation Script (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/check.js:8-20`):**
```javascript
page.onAlert = function(msg) {
  console.log(msg);  // Detects alert() → prints to stdout
};

page.onConfirm = function(msg) {
  console.log(msg);  // Detects confirm() → prints to stdout
};

page.onPrompt = function(msg) {
  console.log(msg);  // Detects prompt() → prints to stdout
};

page.open(input, function(status) {
  // Executes JavaScript in full browser context
});
```

**Render Context:** Full HTML document executed in PhantomJS WebKit browser engine

**Sink Type:** HTML Body Context → Full JavaScript execution environment

**Why It's Exploitable:**

1. **Unrestricted JavaScript Execution:** PhantomJS runs with full JavaScript capabilities (DOM manipulation, network requests, storage APIs)
2. **No Sandboxing:** PhantomJS process runs as root with no seccomp/AppArmor restrictions
3. **User-Controlled HTML:** Entire HTML document (`page` parameter) contains XSS payload from Sink #1

**Execution Flow:**
```
XSS Payload (from Sink #1) → HTML file written → PhantomJS loads file → JavaScript executes → alert() detected → Flag disclosed
```

**Security Implication:** This sink is the **validation mechanism** for Sink #1. The vulnerability chain requires both:
1. Bypassing input validation to inject XSS (Sink #1)
2. Triggering PhantomJS execution that detects `alert()` (Sink #2)

**Additional Risk:** PhantomJS 2.1.1 (abandoned 2018) has unpatched vulnerabilities. If PhantomJS RCE discovered in future, this sink becomes container escape vector (running as root).

### Additional XSS Contexts Analyzed (NOT VULNERABLE)

**HTML Attribute Context:** ✅ SAFE
- No user input flows into `onclick`, `onerror`, `href`, `src` attributes
- All attributes use hardcoded values from `constants.py`

**CSS Context:** ✅ SAFE
- No user input in `style` attributes or `<style>` tags
- All CSS in static files (`/static/css/`)

**URL Context:** ✅ SAFE
- No user input in `href`, `src`, `action`, or `formaction` attributes
- URL generation uses server-controlled random hex: `url = 'http://localhost:5000/' + fn` (line 36)

**eval()/Function()/setTimeout() Context:** ✅ NOT PRESENT
- No `eval()` calls in application code
- No `new Function()` constructors
- No `setTimeout(string)` or `setInterval(string)` usage
- PhantomJS `check.js` uses function callbacks only

**Template Injection:** ✅ NOT VULNERABLE
- No `render_template_string()` with user input
- HTML templates are hardcoded constants, not user-controllable

### XSS Prevention Mechanisms (ALL MISSING)

**Missing Defenses:**
- ❌ No Content Security Policy (CSP)
- ❌ No HTML entity encoding
- ❌ No JavaScript context escaping
- ❌ No output encoding libraries (OWASP ESAPI, DOMPurify)
- ⚠️ X-XSS-Protection: 0 (browser filter **explicitly disabled**)

**What Proper Defense Would Look Like (NOT IMPLEMENTED):**
```python
# This code DOES NOT EXIST in the application
import json

# JavaScript context escaping via JSON encoding
safe_msg = json.dumps(msg)[1:-1]  # Remove JSON quotes
script_content = f'<script>var name = "{safe_msg}"; document.write("Hello " + name);</script>'

# Content Security Policy
response.headers["Content-Security-Policy"] = "default-src 'self'; script-src 'self'; object-src 'none';"

# Enable XSS protection (instead of disabling it)
response.headers["X-XSS-Protection"] = "1; mode=block"
```

---

## 10. SSRF Sinks

### SSRF Analysis Result: NO EXPLOITABLE VULNERABILITIES FOUND

After comprehensive analysis of all potential Server-Side Request Forgery (SSRF) attack vectors, this application contains **ZERO exploitable SSRF vulnerabilities** in network-accessible components.

### HTTP(S) Clients - NO SSRF RISK

**urllib Import Analysis:**
- **File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:9`
- **Code:** `import urllib`
- **Usage:** ❌ **NEVER INVOKED** - Dead import with zero calls to `urllib.urlopen()`, `urllib.request.urlopen()`, or `urllib.urlretrieve()`

**Verification:**
```bash
grep -rn "urllib\." /Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/
# Result: No matches - urllib imported but never used
```

**Other HTTP Clients:**
- ❌ No `requests` library (not in requirements.txt)
- ❌ No `httpx`, `aiohttp`, `urllib3`
- ❌ No `curl` subprocess calls
- ❌ No `wget` subprocess calls

**Finding:** No HTTP client code exists that could be manipulated for SSRF.

### Headless Browsers & Render Engines - NO SSRF RISK

**PhantomJS Analysis:**
- **File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/src/app.py:34-36`
- **Code:**
  ```python
  proc = subprocess.Popen(["timeout","5","phantomjs", "check.js"],
                         stdout=subprocess.PIPE, stdin=subprocess.PIPE)
  fn = "static/" + os.urandom(16).encode('hex') + '.html'
  url = 'http://localhost:5000/' + fn  # ← SERVER-CONTROLLED URL
  ```

**URL Construction:**
- **Scheme:** `http://` (hardcoded)
- **Host:** `localhost:5000` (hardcoded)
- **Path:** `static/<random-32-hex>.html` (server-generated)

**User Input Flow:**
```
User Input: ?name=<payload>
    ↓
Embedded in HTML CONTENT
    ↓
Written to file: static/abcd1234...html
    ↓
URL: http://localhost:5000/static/abcd1234...html (SERVER-CONTROLLED)
    ↓
PhantomJS loads: localhost URL only
```

**Why This Is NOT SSRF:**
1. ✅ User input affects file **content**, NOT URL **destination**
2. ✅ Filename is cryptographically random (32-char hex from `os.urandom(16)`)
3. ✅ URL scheme, host, and path prefix are hardcoded
4. ✅ PhantomJS always fetches from `localhost:5000`, never external URLs

**Finding:** PhantomJS loads server-controlled localhost URLs only. No SSRF vector.

### Raw Sockets & Connect APIs - NOT PRESENT

- ❌ No `socket` module imported
- ❌ No `socket.connect()` calls
- ❌ No TCP/UDP client code
- ❌ No network programming beyond Flask's WSGI server

### URL Openers & File Includes - NOT PRESENT

- ❌ No `file_get_contents` (not PHP)
- ❌ No `fopen` with URLs
- ❌ No `include`/`require` with remote resources
- ❌ No `urllib.urlopen()` calls (despite import)

### Redirect & "Next URL" Handlers - NOT PRESENT

- ❌ No `flask.redirect()` with user input
- ❌ No `?next=`, `?return_url=`, `?redirect=` parameter processing
- ❌ No `response.headers['Location']` manipulation
- ❌ No URL validation in redirect chains

**Routes Analyzed:**
```python
@app.route('/')      # Returns static HTML (no redirects)
@app.route('/page')  # Returns XSS challenge page (no redirects)
```

### Media Processors - NOT PRESENT

**Requirements Analysis:**
```
Flask==1.1.4
phantomjs
```

**Missing Media Libraries:**
- ❌ No ImageMagick (`convert`, `identify`)
- ❌ No GraphicsMagick
- ❌ No FFmpeg (video/audio processing)
- ❌ No PIL/Pillow (Python image libraries)
- ❌ No wkhtmltopdf (PDF generation)

### Link Preview & Unfurlers - NOT PRESENT

- ❌ No link preview functionality
- ❌ No OpenGraph metadata fetching
- ❌ No oEmbed endpoint consumers
- ❌ No social media card generators

### Webhook Testers & Callback Verifiers - NOT PRESENT

- ❌ No webhook delivery endpoints
- ❌ No "ping my webhook" features
- ❌ No callback verification
- ❌ No outbound HTTP notifications

### SSO/OIDC Discovery & JWKS Fetchers - NOT PRESENT

- ❌ No authentication mechanisms (see Section 3)
- ❌ No OpenID Connect discovery
- ❌ No JWKS URL fetching
- ❌ No OAuth/SAML metadata retrieval

### Importers & Data Loaders - NOT PRESENT

- ❌ No "import from URL" functionality
- ❌ No CSV/JSON/XML remote loaders
- ❌ No RSS/Atom feed readers
- ❌ No external data synchronization

### Package/Plugin/Theme Installers - NOT PRESENT

- ❌ No "install from URL" features
- ❌ No package manager integration
- ❌ No plugin/theme downloaders

### Monitoring & Health Check Frameworks - NO SSRF RISK

**Docker Health Check (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-087-24/docker-compose.yml:10`):**
```yaml
healthcheck:
  test: timeout 10s bash -c ':> /dev/tcp/127.0.0.1/5000' || exit 1
```

**Analysis:**
- ✅ Hardcoded to `127.0.0.1:5000`
- ✅ No user input in health check
- ✅ Bash TCP pseudo-device (not HTTP request)

### Cloud Metadata Helpers - NOT PRESENT

- ❌ No AWS/GCP/Azure instance metadata calls
- ❌ No cloud service discovery
- ❌ No container orchestration API clients

### SSRF Sink Summary

| Attack Vector | Status | File Location | User Control | SSRF Risk |
|---------------|--------|---------------|--------------|-----------|
| HTTP Clients (urllib, requests) | ❌ Not invoked | app.py:9 (import only) | N/A | **NONE** |
| PhantomJS page.open() | ✅ Found | app.py:36, check.js:20 | **NO** (localhost only) | **NONE** |
| Webhooks/Callbacks | ❌ Not found | - | N/A | **NONE** |
| Redirects | ❌ Not found | - | N/A | **NONE** |
| File Inclusion | ❌ Not found | - | N/A | **NONE** |
| Media Processors | ❌ Not found | - | N/A | **NONE** |
| All Other Vectors | ❌ Not found | - | N/A | **NONE** |

**Total SSRF Sinks:** 0  
**Total Exploitable SSRF Vulnerabilities:** 0

**Conclusion:** This application has **no SSRF attack surface**. The only outbound network request (PhantomJS) uses server-controlled localhost URLs with no user influence on the destination.

---

## CONCLUSION

This code analysis reveals **XBEN-087-24** as a deliberately vulnerable XSS challenge platform with catastrophic security failures across all domains. The application's 338-line codebase contains **one critical exploitable vulnerability** (reflected XSS via newline injection) that enables complete compromise through flag disclosure, alongside systemic security weaknesses including zero authentication, disabled browser protections, end-of-life software stack, secrets in version control, and complete absence of defense-in-depth.

**Critical Findings Summary:**
- ✅ **1 Critical XSS Vulnerability** - Exploitable via newline injection at `/page?name=`
- ✅ **0 SSRF Vulnerabilities** - No exploitable server-side request forgery
- ✅ **0 SQL Injection Vulnerabilities** - No database interaction
- ✅ **0 Authentication Mechanisms** - Complete absence of identity verification
- ✅ **Secrets Exposed** - Flag in git, Docker layers, and plaintext files
- ✅ **EOL Stack** - Python 2.7.18 (EOL 2020), PhantomJS (abandoned 2018)
- ✅ **No Rate Limiting** - Unlimited PhantomJS spawning enables DoS

**For Penetration Testers:** Focus exploitation efforts on the `/page` endpoint XSS vulnerability (Section 9, Sink #1). The weak character blacklist is bypassable via newline injection (`%0a`), enabling JavaScript execution that triggers PhantomJS alert detection and flag disclosure. All other attack surfaces (authentication bypass, SQL injection, SSRF, command injection) are non-existent due to feature absence.

**For Security Assessment:** This application represents a **complete security failure** suitable only for training environments. Production deployment would require full architectural redesign with authentication, modern framework versions, security headers, TLS/HTTPS, input validation overhaul, and secrets management implementation.